Repository: python/mypy

Issue:
isinstance() tuple unpacking raises mypy internal error
The tuple unpacking here ...
```
two_types = (list, tuple)                                                       
third_type = str                                                                
if isinstance('text', (*two_types, third_type)):                                
    print('hello')                                                              
```
... produces ...
```
mypy --show-traceback test.py
test.py:3: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.560
Traceback (most recent call last):
  File "/Users/trevorbaca/.virtualenvs/abjad3/bin/mypy", line 11, in <module>
    sys.exit(console_entry())
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/main.py", line 66, in main
    res = type_check_only(sources, bin_dir, options)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/main.py", line 119, in type_check_only
    options=options)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/build.py", line 218, in build
    graph = dispatch(sources, manager)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/build.py", line 1997, in dispatch
    process_graph(graph, manager)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/build.py", line 2299, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/build.py", line 2475, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/build.py", line 1876, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checker.py", line 196, in check_first_pass
    self.accept(d)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checker.py", line 286, in accept
    stmt.accept(self)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/nodes.py", line 921, in accept
    return visitor.visit_if_stmt(self)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checker.py", line 2181, in visit_if_stmt
    t = self.expr_checker.accept(e)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checkexpr.py", line 2365, in accept
    typ = node.accept(self)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/nodes.py", line 1245, in accept
    return visitor.visit_call_expr(self)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checkexpr.py", line 271, in visit_call_expr
    self.check_runtime_protocol_test(e)
  File "/Users/trevorbaca/.virtualenvs/abjad3/lib/python3.6/site-packages/mypy/checkexpr.py", line 283, in check_runtime_protocol_test
    tp = self.chk.type_map[expr]
KeyError: <mypy.nodes.StarExpr object at 0x10cb639b0>
test.py:3: : note: use --pdb to drop into pdb
```
... when run by mypy.


Discussion:
Confirmed on master and in release-0.600.
(This looks like an old bug so setting priority to normal.)

Resolving patch:
diff --git a/mypy/checker.py b/mypy/checker.py
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -3949,6 +3949,8 @@ def flatten(t: Expression) -> List[Expression]:
     """Flatten a nested sequence of tuples/lists into one list of nodes."""
     if isinstance(t, TupleExpr) or isinstance(t, ListExpr):
         return [b for a in t.items for b in flatten(a)]
+    elif isinstance(t, StarExpr):
+        return flatten(t.expr)
     else:
         return [t]
 


Test patch:
diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test
--- a/test-data/unit/check-isinstance.test
+++ b/test-data/unit/check-isinstance.test
@@ -2207,3 +2207,29 @@ def bar(x: Union[List[str], List[int], None]) -> None:
     assert isinstance(x, list)
     reveal_type(x)                  # E: Revealed type is 'Union[builtins.list[builtins.str], builtins.list[builtins.int]]'
 [builtins fixtures/isinstancelist.pyi]
+
+[case testIsInstanceWithStarExpression]
+from typing import Union, List, Tuple
+
+def f(var: Union[List[str], Tuple[str, str], str]) -> None:
+    reveal_type(var)  # E: Revealed type is 'Union[builtins.list[builtins.str], Tuple[builtins.str, builtins.str], builtins.str]'
+    if isinstance(var, (list, *(str, int))):
+        reveal_type(var)  # E: Revealed type is 'Union[builtins.list[builtins.str], builtins.str]'
+[builtins fixtures/isinstancelist.pyi]
+
+[case testIsInstanceWithStarExpressionAndVariable]
+from typing import Union
+
+def f(var: Union[int, str]) -> None:
+    reveal_type(var)  # E: Revealed type is 'Union[builtins.int, builtins.str]'
+    some_types = (str, tuple)
+    another_type = list
+    if isinstance(var, (*some_types, another_type)):
+        reveal_type(var)  # E: Revealed type is 'builtins.str'
+[builtins fixtures/isinstancelist.pyi]
+
+[case testIsInstanceWithWrongStarExpression]
+var = 'some string'
+if isinstance(var, *(str, int)):  # E: Too many arguments for "isinstance"
+    pass
+[builtins fixtures/isinstancelist.pyi]