Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions mypy/typeops.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
17 changes: 17 additions & 0 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading