# Buggy code
def map_actuals_to_formals(
    caller_kinds: List[int],
    caller_names: List[str],
    callee_kinds: List[int],
    callee_names: List[str],
    caller_arg_type: Callable[[int], Type],
) -> List[List[int]]:
    """Calculate mapping between actual (caller) args and formals.

    The result contains a list of caller argument indexes mapping to each
    callee argument index, indexed by callee index.

    The caller_arg_type argument should evaluate to the type of the actual
    argument type with the given index.
    """
    ncallee = len(callee_kinds)
    map = [None] * ncallee  # type: List[List[int]]
    for i in range(ncallee):
        map[i] = []
    j = 0
    for i, kind in enumerate(caller_kinds):
        if kind == nodes.ARG_POS:
            if j < ncallee:
                if callee_kinds[j] in [nodes.ARG_POS, nodes.ARG_OPT, nodes.ARG_NAMED]:
                    map[j].append(i)
                    j += 1
                elif callee_kinds[j] == nodes.ARG_STAR:
                    map[j].append(i)
        elif kind == nodes.ARG_STAR:
            # We need to know the actual type to map varargs.
            argt = caller_arg_type(i)
            if isinstance(argt, TupleType):
                # A tuple actual maps to a fixed number of formals.
                for _ in range(len(argt.items)):
                    if j < ncallee:
                        if callee_kinds[j] != nodes.ARG_STAR2:
                            map[j].append(i)
                        else:
                            raise NotImplementedError()
                        j += 1
            else:
                # Assume that it is an iterable (if it isn't, there will be
                # an error later).
                while j < ncallee:
                    if callee_kinds[j] in (nodes.ARG_NAMED, nodes.ARG_STAR2):
                        break
                    else:
                        map[j].append(i)
                    j += 1
        elif kind == nodes.ARG_NAMED:
            name = caller_names[i]
            if name in callee_names:
                map[callee_names.index(name)].append(i)
            elif nodes.ARG_STAR2 in callee_kinds:
                map[callee_kinds.index(nodes.ARG_STAR2)].append(i)
        else:
            assert kind == nodes.ARG_STAR2
            for j in range(ncallee):
                # TODO tuple varargs complicate this
                no_certain_match = (
                    not map[j] or caller_kinds[map[j][0]] == nodes.ARG_STAR
                )
                if (callee_names[j] and no_certain_match) or callee_kinds[
                    j
                ] == nodes.ARG_STAR2:
                    map[j].append(i)
    return map


# Traceback (NotImplementedError)
Traceback (most recent call last):
File "./.tox/mypy/bin/mypy", line 6, in <module>
main(__file__)
File ".../mypy/main.py", line 54, in main
res = type_check_only(sources, bin_dir, options)
File ".../mypy/main.py", line 102, in type_check_only
python_path=options.python_path)
File ".../mypy/build.py", line 209, in build
dispatch(sources, manager)
File ".../mypy/build.py", line 1321, in dispatch
process_graph(graph, manager)
File ".../mypy/build.py", line 1452, in process_graph
process_stale_scc(graph, scc)
File ".../mypy/build.py", line 1482, in process_stale_scc
graph[id].type_check()
File ".../mypy/build.py", line 1301, in type_check
manager.type_checker.visit_file(self.tree, self.xpath)
File ".../mypy/checker.py", line 419, in visit_file
self.accept(d)
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 650, in accept
return visitor.visit_class_def(self)
File ".../mypy/checker.py", line 1049, in visit_class_def
self.accept(defn.defs)
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 715, in accept
return visitor.visit_block(self)
File ".../mypy/checker.py", line 1144, in visit_block
self.accept(s)
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 531, in accept
return visitor.visit_decorator(self)
File ".../mypy/checker.py", line 1934, in visit_decorator
e.func.accept(self)
File ".../mypy/nodes.py", line 462, in accept
return visitor.visit_func_def(self)
File ".../mypy/checker.py", line 573, in visit_func_def
self.check_func_item(defn, name=defn.name())
File ".../mypy/checker.py", line 631, in check_func_item
self.check_func_def(defn, typ, name)
File ".../mypy/checker.py", line 739, in check_func_def
self.accept_in_frame(item.body)
File ".../mypy/checker.py", line 475, in accept_in_frame
answer = self.accept(node, type_context)
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 715, in accept
return visitor.visit_block(self)
File ".../mypy/checker.py", line 1144, in visit_block
self.accept(s)
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 753, in accept
return visitor.visit_assignment_stmt(self)
File ".../mypy/checker.py", line 1153, in visit_assignment_stmt
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None)
File ".../mypy/checker.py", line 1203, in check_assignment
self.infer_variable_type(inferred, lvalue, self.accept(rvalue),
File ".../mypy/checker.py", line 460, in accept
typ = node.accept(self)
File ".../mypy/nodes.py", line 1185, in accept
return visitor.visit_call_expr(self)
File ".../mypy/checker.py", line 1992, in visit_call_expr
return self.expr_checker.visit_call_expr(e)
File ".../mypy/checkexpr.py", line 141, in visit_call_expr
return self.check_call_expr_with_callee_type(callee_type, e)
File ".../mypy/checkexpr.py", line 192, in check_call_expr_with_callee_type
e.arg_names, callable_node=e.callee)[0]
File ".../mypy/checkexpr.py", line 226, in check_call
lambda i: self.accept(args[i]))
File ".../mypy/checkexpr.py", line 1570, in map_actuals_to_formals
raise NotImplementedError()
NotImplementedError:

*** INTERNAL ERROR ***

qutebrowser/browser/webpage.py:344: error: Internal error -- please report a bug at https://github.com/python/mypy/issues

# Fixed code
def map_actuals_to_formals(
    caller_kinds: List[int],
    caller_names: List[str],
    callee_kinds: List[int],
    callee_names: List[str],
    caller_arg_type: Callable[[int], Type],
) -> List[List[int]]:
    """Calculate mapping between actual (caller) args and formals.

    The result contains a list of caller argument indexes mapping to each
    callee argument index, indexed by callee index.

    The caller_arg_type argument should evaluate to the type of the actual
    argument type with the given index.
    """
    ncallee = len(callee_kinds)
    map = [[] for i in range(ncallee)]  # type: List[List[int]]
    j = 0
    for i, kind in enumerate(caller_kinds):
        if kind == nodes.ARG_POS:
            if j < ncallee:
                if callee_kinds[j] in [nodes.ARG_POS, nodes.ARG_OPT, nodes.ARG_NAMED]:
                    map[j].append(i)
                    j += 1
                elif callee_kinds[j] == nodes.ARG_STAR:
                    map[j].append(i)
        elif kind == nodes.ARG_STAR:
            # We need to know the actual type to map varargs.
            argt = caller_arg_type(i)
            if isinstance(argt, TupleType):
                # A tuple actual maps to a fixed number of formals.
                for _ in range(len(argt.items)):
                    if j < ncallee:
                        if callee_kinds[j] != nodes.ARG_STAR2:
                            map[j].append(i)
                        else:
                            break
                        j += 1
            else:
                # Assume that it is an iterable (if it isn't, there will be
                # an error later).
                while j < ncallee:
                    if callee_kinds[j] in (nodes.ARG_NAMED, nodes.ARG_STAR2):
                        break
                    else:
                        map[j].append(i)
                    j += 1
        elif kind == nodes.ARG_NAMED:
            name = caller_names[i]
            if name in callee_names:
                map[callee_names.index(name)].append(i)
            elif nodes.ARG_STAR2 in callee_kinds:
                map[callee_kinds.index(nodes.ARG_STAR2)].append(i)
        else:
            assert kind == nodes.ARG_STAR2
            for j in range(ncallee):
                # TODO tuple varargs complicate this
                no_certain_match = (
                    not map[j] or caller_kinds[map[j][0]] == nodes.ARG_STAR
                )
                if (callee_names[j] and no_certain_match) or callee_kinds[
                    j
                ] == nodes.ARG_STAR2:
                    map[j].append(i)
    return map