-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Labels
bugmypy got something wrongmypy got something wrong
Description
Type narrowing behaves inconsistently:
def f(x: str | int) -> None:
if x == "x":
reveal_type(x) # str | int
if x in ["x"]:
reveal_type(x) # strBoth of these should infer the same type. This is a regression that was introduced in #17344 (cc @Jordandev678).
Also, unlike with ==, narrowing using "in" doesn't consider the possibility of a custom __eq__ method, so it can infer the wrong type:
class C:
def __init__(self, x: int) -> None:
self.x = x
def __eq__(self, other: object) -> bool:
if isinstance(other, C) and other.x == self.x:
return True
return NotImplemented
class D(C):
pass
def f(x: C) -> None:
if x in [D(5)]:
print(type(x)) # C
reveal_type(x) # D
f(C(5))I'm going to revert to #17344 since fixing the logic may be non-trivial, and there is also another related bug (#17841).
The original PR can be submitted again with a fix that uses the same logic we use for == narrowing. If there is desire to support more narrowing use cases, this should be addressed in a separate issue/PR, and both == and "in" narrowing should remain consistent.
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrong