You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dataclasses fail to narrow with issubclass() in Python >= 3.13 #21635
With Python >= 3.13, given cls: type[A] and if issubclass(cls, M) where A and M are dataclasses, mypy is unable to narrow the type of cls to type[M]. Instead, the guarded block is not typechecked at all.
When iterating over a list[type[A]] in a comprehension with if issubclass(cls, M) where A and M are dataclasses, mypy is unable to narrow the type of cls to type[M]. Instead, the comprehension result expression is typechecked with cls at its original unnarrowed type type[A].
@apoorvdarshan Thanks for the PR. However, it does not solve the problem. It only masks the type error by incorrectly typing the classes as Never. In fact, this is not an impossible type - as you can see from the repro in the description, the intersection of the types is not empty.
Thanks to your PR, I have made the issue title and repro more precise. Note that the PR does not include the repro in its tests. If it included the original repro the test would have passed, but only because the error is masked. The current more precise repro would still fail.
The PR still might have merit for the case where the type is actually impossible, as in the tests supplied in the PR. But that discussion would be out of scope here; perhaps open a separate issue for that case.
changed the title [-]Dataclasses fail to narrow in Python >= 3.13[/-][+]Dataclasses fail to narrow with `issubclass()` in Python >= 3.13[/+]on Jul 5, 2026
This turns out to be a regression for dataclasses in Python >= 3.13, caused by the introduction of auto-generated __replace__() methods.
Comprehensions are not required to hit this bug, though the effect of the bug is different for comprehensions.
Root cause: When mypy compares the types of two unrelated dataclasses in issubclass(), the new auto-generated __replace__() methods always cause it to think that the dataclasses are incompatible and assigns the type Never. This causes the broken behaviors described in the reproductions.
I updated the title and description yet again to make them even more precise. I submitted a PR.
The "regular for loop" case in the description works only because the guarded block is not typechecked at all. I added a better reproduction for that, so this case is no longer interesting.
The TypeIs case in the description turns out to be a completely different failure mode and so out of scope here. I will open a separate issue for that.
There is a similar failure for NamedTuple. That too is a completely different failure mode and out of scope here. I'll open a separate issue also for that one.
Activity
[-]issubclass() fails to narrow dataclasses in comprehensions[/-][+]Dataclasses fail to narrow in comprehensions[/+]ygale commentedon Jul 5, 2026
@apoorvdarshan Thanks for the PR. However, it does not solve the problem. It only masks the type error by incorrectly typing the classes as
Never. In fact, this is not an impossible type - as you can see from the repro in the description, the intersection of the types is not empty.Thanks to your PR, I have made the issue title and repro more precise. Note that the PR does not include the repro in its tests. If it included the original repro the test would have passed, but only because the error is masked. The current more precise repro would still fail.
The PR still might have merit for the case where the type is actually impossible, as in the tests supplied in the PR. But that discussion would be out of scope here; perhaps open a separate issue for that case.
[-]Dataclasses fail to narrow in comprehensions[/-][+]Dataclasses fail to narrow in Python >= 3.13[/+][-]Dataclasses fail to narrow in Python >= 3.13[/-][+]Dataclasses fail to narrow with `issubclass()` in Python >= 3.13[/+]ygale commentedon Jul 5, 2026
This turns out to be a regression for dataclasses in Python >= 3.13, caused by the introduction of auto-generated
__replace__()methods.Comprehensions are not required to hit this bug, though the effect of the bug is different for comprehensions.
Root cause: When mypy compares the types of two unrelated dataclasses in
issubclass(), the new auto-generated__replace__()methods always cause it to think that the dataclasses are incompatible and assigns the typeNever. This causes the broken behaviors described in the reproductions.I updated the title and description yet again to make them even more precise. I submitted a PR.
The "regular for loop" case in the description works only because the guarded block is not typechecked at all. I added a better reproduction for that, so this case is no longer interesting.
The
TypeIscase in the description turns out to be a completely different failure mode and so out of scope here. I will open a separate issue for that.There is a similar failure for
NamedTuple. That too is a completely different failure mode and out of scope here. I'll open a separate issue also for that one.Add regression test for plain issubclass() narrowing (no comprehension)
Fix regression in dataclass narrowing for Python >= 3.13 (python#21675)