Repository: python/mypy

Issue:
Internal error when unpacking (asterisk) is used in a list
``` py
tail = ['b', 'c']
['a', *tail]
```

```
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/python3.5/site-packages/mypy/__main__.py", line 5, in <module>
    main(None)
  File "/usr/local/lib/python3.5/site-packages/mypy/main.py", line 40, in main
    res = type_check_only(sources, bin_dir, options)
  File "/usr/local/lib/python3.5/site-packages/mypy/main.py", line 81, in type_check_only
    options=options)
  File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 177, in build
    dispatch(sources, manager)
  File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1323, in dispatch
    process_graph(graph, manager)
  File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1461, in process_graph
    process_stale_scc(graph, scc)
  File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1538, in process_stale_scc
    graph[id].type_check()
  File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1301, in type_check
    manager.type_checker.visit_file(self.tree, self.xpath)
  File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 152, in visit_file
    self.accept(d)
  File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 201, in accept
    typ = node.accept(self)
  File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 737, in accept
    return visitor.visit_expression_stmt(self)
  File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1333, in visit_expression_stmt
    self.accept(s.expr)
  File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 201, in accept
    typ = node.accept(self)
  File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 1445, in accept
    return visitor.visit_list_expr(self)
  File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1859, in visit_list_expr
    return self.expr_checker.visit_list_expr(e)
  File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 1283, in visit_list_expr
    e)
  File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 1303, in check_list_or_set_expr
    [nodes.ARG_POS] * len(items), context)[0]
  File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 253, in check_call
    messages=arg_messages)
  File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 677, in check_argument_types
    actual + 1, i + 1, callee, context, messages)
  File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 702, in check_arg
    elif not is_subtype(caller_type, callee_type):
  File "/usr/local/lib/python3.5/site-packages/mypy/subtypes.py", line 51, in is_subtype
    return left.accept(SubtypeVisitor(right, type_parameter_checker))
AttributeError: 'NoneType' object has no attribute 'accept'

*** INTERNAL ERROR ***

unpacking.py:3: error: Internal error -- please report a bug at https://github.com/python/mypy/issues

NOTE: you can use "mypy --pdb ..." to drop into the debugger when this happens.
```

Related to #704.



Discussion:
I guess we either have to support PEP 448 or at least defend against the crash.

FWIW I debugged the crash a bit and it has already issued the error "Can use starred expression only as assignment target", but apparently it barrels on and tries to call check_arg() with the None that came from failing to infer the starred expression's type.

I'll just put in a None check to avoid this.


Resolving patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -661,6 +661,8 @@ def check_argument_types(self, arg_types: List[Type], arg_kinds: List[int],
         for i, actuals in enumerate(formal_to_actual):
             for actual in actuals:
                 arg_type = arg_types[actual]
+                if arg_type is None:
+                    continue  # Some kind of error was already reported.
                 # Check that a *arg is valid as varargs.
                 if (arg_kinds[actual] == nodes.ARG_STAR and
                         not self.is_valid_var_arg(arg_type)):


Test patch:
diff --git a/test-data/unit/check-lists.test b/test-data/unit/check-lists.test
--- a/test-data/unit/check-lists.test
+++ b/test-data/unit/check-lists.test
@@ -62,3 +62,7 @@ class C: pass
 [builtins fixtures/list.py]
 [out]
 main: note: In function "f":
+
+[case testListContainingStarExpr]
+a = [1, *[2]]  # E: Can use starred expression only as assignment target
+[builtins fixtures/list.py]
diff --git a/test-data/unit/semanal-errors.test b/test-data/unit/semanal-errors.test
--- a/test-data/unit/semanal-errors.test
+++ b/test-data/unit/semanal-errors.test
@@ -487,9 +487,11 @@ c = 1
 d = 1
 a = *b
 a = b, (c, *d)
+a = [1, *[2]]
 [out]
 main:4: error: Can use starred expression only as assignment target
 main:5: error: Can use starred expression only as assignment target
+main:6: error: Can use starred expression only as assignment target
 
 [case testStarExpressionInExp]
 a = 1