Skip to content

Commit

Permalink
Allow variables inside isinstance (#3070)
Browse files Browse the repository at this point in the history
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".
  • Loading branch information
pkch authored and JukkaL committed Apr 3, 2017
1 parent ad2b32e commit 62d4bc8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
6 changes: 2 additions & 4 deletions mypy/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ def _get(self, key: Key, index: int=-1) -> Type:
return None

def put(self, expr: Expression, typ: Type) -> None:
# TODO: replace with isinstance(expr, BindableTypes)
if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)):
if not isinstance(expr, BindableTypes):
return
if not expr.literal:
return
Expand Down Expand Up @@ -203,8 +202,7 @@ def assign_type(self, expr: Expression,
type: Type,
declared_type: Type,
restrict_any: bool = False) -> None:
# TODO: replace with isinstance(expr, BindableTypes)
if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)):
if not isinstance(expr, BindableTypes):
return None
if not expr.literal:
return
Expand Down
10 changes: 9 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2756,8 +2756,16 @@ def flatten(t: Expression) -> List[Expression]:
return [t]


def flatten_types(t: Type) -> List[Type]:
"""Flatten a nested sequence of tuples into one list of nodes."""
if isinstance(t, TupleType):
return [b for a in t.items for b in flatten_types(a)]
else:
return [t]


def get_isinstance_type(expr: Expression, type_map: Dict[Expression, Type]) -> List[TypeRange]:
all_types = [type_map[e] for e in flatten(expr)]
all_types = flatten_types(type_map[expr])
types = [] # type: List[TypeRange]
for type in all_types:
if isinstance(type, FunctionLike) and type.is_type_obj():
Expand Down
16 changes: 16 additions & 0 deletions test-data/unit/check-isinstance.test
Original file line number Diff line number Diff line change
Expand Up @@ -1412,3 +1412,19 @@ def f(x: Union[int, A], a: Type[A]) -> None:

[builtins fixtures/isinstancelist.pyi]


[case testIsinstanceVariableSubstitution]
T = (int, str)
U = (list, T)
x: object = None

if isinstance(x, T):
reveal_type(x) # E: Revealed type is 'Union[builtins.int, builtins.str]'

if isinstance(x, U):
reveal_type(x) # E: Revealed type is 'Union[builtins.list[Any], builtins.int, builtins.str]'

if isinstance(x, (set, (list, T))):
reveal_type(x) # E: Revealed type is 'Union[builtins.set[Any], builtins.list[Any], builtins.int, builtins.str]'

[builtins fixtures/isinstancelist.pyi]

0 comments on commit 62d4bc8

Please sign in to comment.