Skip to content

Commit f295bb8

Browse files
authored
Avoid spurious non-overlapping eq error with metaclass with __eq__ (#19220)
Currently, doing an `==` on a `type[Foo]` where `Foo` has a metaclass that defines `__eq__` will spuriously produce a non-overlapping equality error, because `custom_special_method`, a helper used in the check, does not consider the `TypeType` case. Fix that.
1 parent ab61ec2 commit f295bb8

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

mypy/typeops.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,10 @@ def custom_special_method(typ: Type, name: str, check_all: bool = False) -> bool
11901190
if isinstance(typ, FunctionLike) and typ.is_type_obj():
11911191
# Look up __method__ on the metaclass for class objects.
11921192
return custom_special_method(typ.fallback, name, check_all)
1193+
if isinstance(typ, TypeType) and isinstance(typ.item, Instance):
1194+
if typ.item.type.metaclass_type:
1195+
# Look up __method__ on the metaclass for class objects.
1196+
return custom_special_method(typ.item.type.metaclass_type, name, check_all)
11931197
if isinstance(typ, AnyType):
11941198
# Avoid false positives in uncertain cases.
11951199
return True

test-data/unit/check-expressions.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,14 @@ class Custom(metaclass=CustomMeta): ...
21722172
Normal == int() # E: Non-overlapping equality check (left operand type: "type[Normal]", right operand type: "int")
21732173
Normal == Normal
21742174
Custom == int()
2175+
2176+
n: type[Normal] = Normal
2177+
c: type[Custom] = Custom
2178+
2179+
n == int() # E: Non-overlapping equality check (left operand type: "type[Normal]", right operand type: "int")
2180+
n == n
2181+
c == int()
2182+
21752183
[builtins fixtures/bool.pyi]
21762184

21772185
[case testCustomContainsCheckStrictEquality]

0 commit comments

Comments
 (0)