Skip to content

Commit cae5d3c

Browse files
authored
Narrow type with typevar when the upper bound is a subtype (#10658)
Fixes #10605
1 parent 416f57b commit cae5d3c

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

mypy/meet.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
7070
for x in narrowed.relevant_items()])
7171
elif isinstance(narrowed, AnyType):
7272
return narrowed
73+
elif isinstance(narrowed, TypeVarType) and is_subtype(narrowed.upper_bound, declared):
74+
return narrowed
7375
elif isinstance(declared, TypeType) and isinstance(narrowed, TypeType):
7476
return TypeType.make_normalized(narrow_declared_type(declared.item, narrowed.item))
7577
elif (isinstance(declared, TypeType)

test-data/unit/check-narrowing.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,3 +1073,23 @@ def f(t: Type[C]) -> None:
10731073
else:
10741074
reveal_type(t) # N: Revealed type is "Type[__main__.C]"
10751075
reveal_type(t) # N: Revealed type is "Type[__main__.C]"
1076+
1077+
[case testNarrowingUsingTypeVar]
1078+
# flags: --strict-optional
1079+
from typing import Type, TypeVar
1080+
1081+
class A: pass
1082+
class B(A): pass
1083+
1084+
T = TypeVar("T", bound=A)
1085+
1086+
def f(t: Type[T], a: A, b: B) -> None:
1087+
if type(a) is t:
1088+
reveal_type(a) # N: Revealed type is "T`-1"
1089+
else:
1090+
reveal_type(a) # N: Revealed type is "__main__.A"
1091+
1092+
if type(b) is t:
1093+
reveal_type(b) # N: Revealed type is "<nothing>"
1094+
else:
1095+
reveal_type(b) # N: Revealed type is "__main__.B"

0 commit comments

Comments
 (0)