diff --git a/mypy/typeops.py b/mypy/typeops.py index 866eb72ede3e..88b3c5da48ce 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -521,18 +521,16 @@ def callable_corresponding_argument( # def right(a: int = ...) -> None: ... # def left(__a: int = ..., *, a: int = ...) -> None: ... - from mypy.subtypes import is_subtype + from mypy.meet import meet_types if ( not (by_name.required or by_pos.required) and by_pos.name is None and by_name.pos is None ): - # We actually want the intersection of by_name.typ and by_pos.typ - if is_subtype(by_name.typ, by_pos.typ): - return FormalArgument(by_name.name, by_pos.pos, by_name.typ, False) - if is_subtype(by_pos.typ, by_name.typ): - return FormalArgument(by_name.name, by_pos.pos, by_pos.typ, False) + return FormalArgument( + by_name.name, by_pos.pos, meet_types(by_name.typ, by_pos.typ), False + ) return by_name if by_name is not None else by_pos diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 560d4a5c12fc..be55a182b87b 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -246,6 +246,23 @@ def foo(*args: int | str, **kw: int) -> None: pass [builtins fixtures/tuple.pyi] +[case testTypeCheckOverloadImplOverlapVarArgsAndKwargsUnion] +from __future__ import annotations +from typing import overload + +class Foo: ... + +@overload +def foo(x: int) -> None: ... +@overload +def foo(*, x: Foo) -> None: ... +@overload +def foo(a: str, /) -> None: ... + +def foo(*args: int | str, **kw: int | Foo) -> None: + pass +[builtins fixtures/tuple.pyi] + [case testTypeCheckOverloadWithImplTooSpecificRetType] from typing import overload, Any