Skip to content

Commit 62d4bc8

Browse files
pkchJukkaL
authored andcommitted
Allow variables inside isinstance (#3070)
Fixes #3068 This would allow the use of variables inside the second argument to isinstance/issubclass, as long as those variables are assigned a tuple of types in a "visible range".
1 parent ad2b32e commit 62d4bc8

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

mypy/binder.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ def _get(self, key: Key, index: int=-1) -> Type:
110110
return None
111111

112112
def put(self, expr: Expression, typ: Type) -> None:
113-
# TODO: replace with isinstance(expr, BindableTypes)
114-
if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)):
113+
if not isinstance(expr, BindableTypes):
115114
return
116115
if not expr.literal:
117116
return
@@ -203,8 +202,7 @@ def assign_type(self, expr: Expression,
203202
type: Type,
204203
declared_type: Type,
205204
restrict_any: bool = False) -> None:
206-
# TODO: replace with isinstance(expr, BindableTypes)
207-
if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)):
205+
if not isinstance(expr, BindableTypes):
208206
return None
209207
if not expr.literal:
210208
return

mypy/checker.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -2756,8 +2756,16 @@ def flatten(t: Expression) -> List[Expression]:
27562756
return [t]
27572757

27582758

2759+
def flatten_types(t: Type) -> List[Type]:
2760+
"""Flatten a nested sequence of tuples into one list of nodes."""
2761+
if isinstance(t, TupleType):
2762+
return [b for a in t.items for b in flatten_types(a)]
2763+
else:
2764+
return [t]
2765+
2766+
27592767
def get_isinstance_type(expr: Expression, type_map: Dict[Expression, Type]) -> List[TypeRange]:
2760-
all_types = [type_map[e] for e in flatten(expr)]
2768+
all_types = flatten_types(type_map[expr])
27612769
types = [] # type: List[TypeRange]
27622770
for type in all_types:
27632771
if isinstance(type, FunctionLike) and type.is_type_obj():

test-data/unit/check-isinstance.test

+16
Original file line numberDiff line numberDiff line change
@@ -1412,3 +1412,19 @@ def f(x: Union[int, A], a: Type[A]) -> None:
14121412

14131413
[builtins fixtures/isinstancelist.pyi]
14141414

1415+
1416+
[case testIsinstanceVariableSubstitution]
1417+
T = (int, str)
1418+
U = (list, T)
1419+
x: object = None
1420+
1421+
if isinstance(x, T):
1422+
reveal_type(x) # E: Revealed type is 'Union[builtins.int, builtins.str]'
1423+
1424+
if isinstance(x, U):
1425+
reveal_type(x) # E: Revealed type is 'Union[builtins.list[Any], builtins.int, builtins.str]'
1426+
1427+
if isinstance(x, (set, (list, T))):
1428+
reveal_type(x) # E: Revealed type is 'Union[builtins.set[Any], builtins.list[Any], builtins.int, builtins.str]'
1429+
1430+
[builtins fixtures/isinstancelist.pyi]

0 commit comments

Comments
 (0)