# Buggy code
def apply_generic_arguments(
    callable: CallableType, types: List[Type], msg: MessageBuilder, context: Context
) -> CallableType:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.
    """
    tvars = callable.variables
    assert len(tvars) == len(types)
    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            if isinstance(type, TypeVarType) and type.values:
                # Allow substituting T1 for T if every allowed value of T1
                # is also a legal value of T.
                if all(any(is_same_type(v, v1) for v in values) for v1 in type.values):
                    continue
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

        upper_bound = callable.variables[i].upper_bound
        if type and not mypy.subtypes.satisfies_upper_bound(type, upper_bound):
            msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[TypeVarId, Type]
    for i, tv in enumerate(tvars):
        if types[i]:
            id_to_type[tv.id] = types[i]

    # Apply arguments to argument types.
    arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]

    # The callable may retain some type vars if only some were applied.
    remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type]

    return callable.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )


# Traceback (AssertionError)
Traceback (most recent call last):
File "/usr/local/bin/mypy", line 6, in <module>
main(__file__)
File "/usr/local/lib/python3.5/site-packages/mypy/main.py", line 54, in main
res = type_check_only(sources, bin_dir, options)
File "/usr/local/lib/python3.5/site-packages/mypy/main.py", line 102, in type_check_only
python_path=options.python_path)
File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 209, in build
dispatch(sources, manager)
File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1325, in dispatch
process_graph(graph, manager)
File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1456, in process_graph
process_stale_scc(graph, scc)
File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1486, in process_stale_scc
graph[id].type_check()
File "/usr/local/lib/python3.5/site-packages/mypy/build.py", line 1305, in type_check
manager.type_checker.visit_file(self.tree, self.xpath)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 424, in visit_file
self.accept(d)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 465, in accept
typ = node.accept(self)
File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 862, in accept
return visitor.visit_if_stmt(self)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1661, in visit_if_stmt
self.accept(b)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 465, in accept
typ = node.accept(self)
File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 715, in accept
return visitor.visit_block(self)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1149, in visit_block
self.accept(s)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 465, in accept
typ = node.accept(self)
File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 753, in accept
return visitor.visit_assignment_stmt(self)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1158, in visit_assignment_stmt
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1175, in check_assignment
infer_lvalue_type)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1244, in check_assignment_to_multiple_lvalues
self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1277, in check_multi_assignment
context, undefined_rvalue, infer_lvalue_type)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1297, in check_multi_assignment_from_tuple
rvalue_type = cast(TupleType, self.accept(rvalue, lvalue_type))
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 465, in accept
typ = node.accept(self)
File "/usr/local/lib/python3.5/site-packages/mypy/nodes.py", line 1185, in accept
return visitor.visit_call_expr(self)
File "/usr/local/lib/python3.5/site-packages/mypy/checker.py", line 1997, in visit_call_expr
return self.expr_checker.visit_call_expr(e)
File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 141, in visit_call_expr
return self.check_call_expr_with_callee_type(callee_type, e)
File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 192, in check_call_expr_with_callee_type
e.arg_names, callable_node=e.callee)[0]
File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 230, in check_call
callee, context)
File "/usr/local/lib/python3.5/site-packages/mypy/checkexpr.py", line 370, in infer_function_type_arguments_using_context
args = infer_type_arguments(callable.type_var_ids(), ret_type, erased_ctx)
File "/usr/local/lib/python3.5/site-packages/mypy/infer.py", line 43, in infer_type_arguments
return solve_constraints(type_var_ids, constraints)
File "/usr/local/lib/python3.5/site-packages/mypy/solve.py", line 50, in solve_constraints
top = meet_types(top, c.target)
File "/usr/local/lib/python3.5/site-packages/mypy/meet.py", line 22, in meet_types
return t.accept(TypeMeetVisitor(s))
File "/usr/local/lib/python3.5/site-packages/mypy/types.py", line 763, in accept
return visitor.visit_partial_type(self)
File "/usr/local/lib/python3.5/site-packages/mypy/meet.py", line 208, in visit_partial_type
assert False, 'Internal error'
AssertionError: Internal error

*** INTERNAL ERROR ***

test.py:5: 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.

# Fixed code
def apply_generic_arguments(
    callable: CallableType, types: List[Type], msg: MessageBuilder, context: Context
) -> CallableType:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.
    """
    tvars = callable.variables
    assert len(tvars) == len(types)
    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            if isinstance(type, TypeVarType) and type.values:
                # Allow substituting T1 for T if every allowed value of T1
                # is also a legal value of T.
                if all(any(is_same_type(v, v1) for v in values) for v1 in type.values):
                    continue
            for value in values:
                if isinstance(type, PartialType) or mypy.subtypes.is_subtype(
                    type, value
                ):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

        upper_bound = callable.variables[i].upper_bound
        if (
            type
            and not isinstance(type, PartialType)
            and not mypy.subtypes.satisfies_upper_bound(type, upper_bound)
        ):
            msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[TypeVarId, Type]
    for i, tv in enumerate(tvars):
        if types[i]:
            id_to_type[tv.id] = types[i]

    # Apply arguments to argument types.
    arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]

    # The callable may retain some type vars if only some were applied.
    remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type]

    return callable.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )