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
[1.16 regression] narrowing on is_dataclass #19139
If you use isinstance(item, type), this used to be used in conjunction with dataclasses.is_dataclass to identify types and instances. It's the recommendation in the CPython documentation, in fact: https://docs.python.org/3/library/dataclasses.html#dataclasses.is_dataclass. However, the latests MyPy no longer narrows this correctly (from what I can tell, unless I'm doing something wrong), and still thinks I might have an instance, which then breaks later when creating an instance, etc.
Note that I can flip the order, in which case I just get builtins.type for both versions. This isn't enough to fix it for some of the more complex usages in scikit-build-core, though.
tmp.py:6: note: Revealed type is "Type[_typeshed.DataclassInstance]"
Actual Behavior
tmp.py:6: note: Revealed type is "Union[_typeshed.DataclassInstance, Type[_typeshed.DataclassInstance]]"
Your Environment
Mypy version used: uvx --from git+https://github.com/python/mypy mypy tmp.py was used, so latest commit, also latest release 1.15 version for comparison.
I get it now. When find_isinstance_check_helper is applied, we check all arguments at once, which means wrong @overload is selected - mypy only stores narrowed types when all typemaps are known. cc @sobolevn as original author of #17678 - this sounds like a painful limitation, any overload resolution here won't take preceding narrowing statements into account.
Splitting the ladder works:
importdataclassesraw_target: objectifisinstance(raw_target, type):
ifdataclasses.is_dataclass(raw_target):
reveal_type(raw_target) # N: Revealed type is "type[_typeshed.DataclassInstance]"
Activity
chore: adjust typing to be ready for next mypy release (#1088)
sterliakov commentedon May 27, 2025
This is a regression, and a rather bad one. Note also that this is somehow dependent on checks order. MRE without stdlib dependency:
https://mypy-play.net/?mypy=master&python=3.13&flags=strict&gist=6e2a57a00f5aa275ebbb2abbefa972e6
My MRE exhibits the same behaviour on 1.15.0, so it isn't the same. And this is correct -
Aandtypecan have a common LSP-compatible subclass.This issue bisects to #17678;
is_dataclassis an overloaded function:And this looks like a bug - after first
isinstancewe should haveraw_targetalready narrowed totype, so the second overload should match.sterliakov commentedon May 27, 2025
@hauntsaninja could you please create a label for PEP 742 / TypeIs?
sterliakov commentedon May 28, 2025
I get it now. When
find_isinstance_check_helperis applied, we check all arguments at once, which means wrong@overloadis selected - mypy only stores narrowed types when all typemaps are known. cc @sobolevn as original author of #17678 - this sounds like a painful limitation, any overload resolution here won't take preceding narrowing statements into account.Splitting the ladder works:
[-]Regression in 1.16 on DataclassInstance?[/-][+][1.16 regression] narrowing on is_dataclass[/+]Revert "Infer correct types with overloads of `Type[Guard | Is]` (#17678
Revert "Infer correct types with overloads of `Type[Guard | Is]` (#19161
Revert "Infer correct types with overloads of `Type[Guard | Is]` (#19161
Revert "Infer correct types with overloads of `Type[Guard | Is]` (pyt…
hauntsaninja commentedon Jun 3, 2025
Looks like PR causing regression was reverted. #19214 adds a regression test on master
Add regression test for dataclass typeguard (#19214)