diff --git a/mypy/meet.py b/mypy/meet.py index c5d25652d7b3..00e72e178ac9 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -249,13 +249,15 @@ def _type_object_overlap(left: ProperType, right: ProperType) -> bool: if isinstance(left, TypeType) and isinstance(right, CallableType) and right.is_type_obj(): return _is_overlapping_types(left.item, right.ret_type) # 2. Type[C] vs Meta, where Meta is a metaclass for C. - if (isinstance(left, TypeType) and isinstance(left.item, Instance) and - isinstance(right, Instance)): - left_meta = left.item.type.metaclass_type - if left_meta is not None: - return _is_overlapping_types(left_meta, right) - # builtins.type (default metaclass) overlaps with all metaclasses - return right.type.has_base('builtins.type') + if isinstance(left, TypeType) and isinstance(right, Instance): + if isinstance(left.item, Instance): + left_meta = left.item.type.metaclass_type + if left_meta is not None: + return _is_overlapping_types(left_meta, right) + # builtins.type (default metaclass) overlaps with all metaclasses + return right.type.has_base('builtins.type') + elif isinstance(left.item, AnyType): + return right.type.has_base('builtins.type') # 3. Callable[..., C] vs Meta is considered below, when we switch to fallbacks. return False diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index 2e34bb4b9e5d..ba4120dea75a 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -2579,20 +2579,35 @@ Bad in subclasses # E: Non-overlapping container check (element type: "Type[Bad [case testStrictEqualityMetaclass] # flags: --strict-equality -from typing import List, Type +from typing import List, Type, Any class Meta(type): ... class OtherMeta(type): ... class A(metaclass=Meta): ... +class B(metaclass=Meta): ... class C(metaclass=OtherMeta): ... o: Type[object] +a: Type[Any] +aa: type exp: List[Meta] A in exp +B in exp C in exp # E: Non-overlapping container check (element type: "Type[C]", container item type: "Meta") + o in exp +a in exp +aa in exp + +a in [A, B] +aa in [A, B] + +class AA: ... +class BB: ... +a in [AA, BB] +aa in [AA, BB] [builtins fixtures/list.pyi] [typing fixtures/typing-full.pyi]