diff --git a/mypy/constraints.py b/mypy/constraints.py index aa4ce24b65df..89b8e4527e24 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -486,12 +486,11 @@ def infer_against_overloaded(self, overloaded: Overloaded, template: CallableType) -> List[Constraint]: # Create constraints by matching an overloaded type against a template. # This is tricky to do in general. We cheat by only matching against - # the first overload item, and by only matching the return type. This + # the first overload item that is callable compatible. This # seems to work somewhat well, but we should really use a more # reliable technique. item = find_matching_overload_item(overloaded, template) - return infer_constraints(template.ret_type, item.ret_type, - self.direction) + return infer_constraints(template, item, self.direction) def visit_tuple_type(self, template: TupleType) -> List[Constraint]: actual = self.actual diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index dc9a94b4a28f..4b3fbfdda851 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -5099,3 +5099,28 @@ def foo(x: MyInt) -> int: ... def foo(x): ... [builtins fixtures/tuple.pyi] + +[case testOverloadedToGeneric] +from typing import TypeVar, Callable, NewType, overload, Union + +# int in our stubs isn't overloaded +class fakeint: + @overload + def __init__(self, x: Union[str, bytes] = ...) -> None: ... + @overload + def __init__(self, x: Union[str, bytes], base: int) -> None: ... + def __init__(self, *args) -> None: pass # type: ignore + + +U = TypeVar('U') +V = TypeVar('V') +W = TypeVar('W') +def compose(f: Callable[[U], V], g: Callable[[W], U]) -> Callable[[W], V]: + return lambda x: f(g(x)) + +ID = NewType("ID", fakeint) + +compose(ID, fakeint)("test") +reveal_type(compose(ID, fakeint)) # N: Revealed type is 'def (Union[builtins.str, builtins.bytes]) -> __main__.ID*' + +[builtins fixtures/tuple.pyi]