Skip to content

Commit 184fb28

Browse files
authored
Implement is_same_type for ErasedType (#1707)
During generic function type inference, the arguments of a lambda may have type ErasedType. If the body of the lambda does isinstance checks on its arguments, mypy would crash inside is_same_type. Fixes #1607.
1 parent ef5e7c5 commit 184fb28

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

mypy/sametypes.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ def visit_uninhabited_type(self, t: UninhabitedType) -> bool:
7474
return isinstance(self.right, UninhabitedType)
7575

7676
def visit_erased_type(self, left: ErasedType) -> bool:
77-
# Should not get here.
78-
raise RuntimeError()
77+
# We can get here when isinstance is used inside a lambda
78+
# whose type is being inferred. In any event, we have no reason
79+
# to think that an ErasedType will end up being the same as
80+
# any other type, even another ErasedType.
81+
return False
7982

8083
def visit_deleted_type(self, left: DeletedType) -> bool:
8184
return isinstance(self.right, DeletedType)

test-data/unit/check-inference-context.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,22 @@ def g(x: Callable[[], int]) -> None: pass
618618
f(lambda: None)
619619
g(lambda: None)
620620

621+
[case testIsinstanceInInferredLambda]
622+
from typing import TypeVar, Callable
623+
T = TypeVar('T')
624+
S = TypeVar('S')
625+
class A: pass
626+
class B(A): pass
627+
class C(A): pass
628+
def f(func: Callable[[T], S], *z: T, r: S = None) -> S: pass
629+
f(lambda x: 0 if isinstance(x, B) else 1) # E: Cannot infer type argument 1 of "f"
630+
f(lambda x: 0 if isinstance(x, B) else 1, A())() # E: "int" not callable
631+
f(lambda x: x if isinstance(x, B) else B(), A(), r=B())() # E: "B" not callable
632+
f( # E: Argument 1 to "f" has incompatible type Callable[[A], A]; expected Callable[[A], B]
633+
lambda x: B() if isinstance(x, B) else x, # E: Incompatible return value type (got "A", expected "B")
634+
A(), r=B())
635+
[builtins fixtures/isinstance.py]
636+
621637

622638
-- Overloads + generic functions
623639
-- -----------------------------

0 commit comments

Comments
 (0)