Repository: python/mypy

Issue:
Internal error when incorrect type annotation
Code fails with internal error:

```
from typing import Any, Dict, Tuple, Union, cast

def foo(a, b):
    # type: (Any) -> None
    pass

foo(0, 1)  # internal error here
```

error

```
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/bin/mypy", line 6, in <module>
    main(__file__)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/main.py", line 54, in main
    type_check_only(sources, bin_dir, options)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/main.py", line 98, in type_check_only
    python_path=options.python_path)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 208, in build
    result = manager.process(initial_states)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 393, in process
    next.process()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/build.py", line 893, in process
    self.type_checker().visit_file(self.tree, self.tree.path)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 405, in visit_file
    self.accept(d)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 446, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 540, in accept
    return visitor.visit_expression_stmt(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1533, in visit_expression_stmt
    self.accept(s.expr)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 446, in accept
    typ = node.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/nodes.py", line 965, in accept
    return visitor.visit_call_expr(self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checker.py", line 1931, in visit_call_expr
    return self.expr_checker.visit_call_expr(e)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 142, in visit_call_expr
    return self.check_call_expr_with_callee_type(callee_type, e)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 193, in check_call_expr_with_callee_type
    e.arg_names, callable_node=e.callee)[0]
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 236, in check_call
    callee, args, arg_kinds, formal_to_actual)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/mypy/checkexpr.py", line 328, in infer_arg_types_in_context2
    res[ai] = self.accept(args[ai], callee.arg_types[i])
IndexError: list index out of range

*** INTERNAL ERROR ***
```



Discussion:
I was able to reproduce the problem. We should probably filter out bad signatures early.

I'll see if I can fix this. There's also an internal error when you do the reverse (the annotation has more types than the function).


Resolving patch:
diff --git a/mypy/parse.py b/mypy/parse.py
--- a/mypy/parse.py
+++ b/mypy/parse.py
@@ -475,12 +475,20 @@ def parse_function(self, no_type_checks: bool=False) -> FuncDef:
 
     def check_argument_kinds(self, funckinds: List[int], sigkinds: List[int],
                              line: int) -> None:
-        """Check that * and ** arguments are consistent.
+        """Check that arguments are consistent.
+
+        This verifies that they have the same number and the kinds correspond.
 
         Arguments:
           funckinds: kinds of arguments in function definition
           sigkinds:  kinds of arguments in signature (after # type:)
         """
+        if len(funckinds) != len(sigkinds):
+            if len(funckinds) > len(sigkinds):
+                self.fail("Type signature has too few arguments", line)
+            else:
+                self.fail("Type signature has too many arguments", line)
+            return
         for kind, token in [(nodes.ARG_STAR, '*'),
                             (nodes.ARG_STAR2, '**')]:
             if ((funckinds.count(kind) != sigkinds.count(kind)) or


Test patch:
diff --git a/mypy/test/data/parse-errors.test b/mypy/test/data/parse-errors.test
--- a/mypy/test/data/parse-errors.test
+++ b/mypy/test/data/parse-errors.test
@@ -294,6 +294,20 @@ def f(x, y: Z): # type: (x, y) -> z
 file: note: In function "f":
 file:1: error: Function has duplicate type signatures
 
+[case testTooManyTypes]
+def f(x, y): # type: (X, Y, Z) -> z
+  pass
+[out]
+file: note: In function "f":
+file:1: error: Type signature has too many arguments
+
+[case testTooFewTypes]
+def f(x, y): # type: (X) -> z
+  pass
+[out]
+file: note: In function "f":
+file:1: error: Type signature has too few arguments
+
 [case testCommentFunctionAnnotationVarArgMispatch]
 def f(x): # type: (*X) -> Y
     pass