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
9 changes: 6 additions & 3 deletions mypy/typeops.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,15 +521,18 @@ def callable_corresponding_argument(

# def right(a: int = ...) -> None: ...
# def left(__a: int = ..., *, a: int = ...) -> None: ...
from mypy.subtypes import is_equivalent
from mypy.subtypes import is_subtype

if (
not (by_name.required or by_pos.required)
and by_pos.name is None
and by_name.pos is None
and is_equivalent(by_name.typ, by_pos.typ)
):
return FormalArgument(by_name.name, by_pos.pos, by_name.typ, False)
# 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 by_name if by_name is not None else by_pos


Expand Down
14 changes: 13 additions & 1 deletion test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,21 @@ def f(x: 'A') -> Any: # E: Overloaded function implementation does not accept al

reveal_type(f(A())) # N: Revealed type is "__main__.B"
reveal_type(f(B())) # N: Revealed type is "__main__.A"

[builtins fixtures/isinstance.pyi]

[case testTypeCheckOverloadImplOverlapVarArgsAndKwargs]
from __future__ import annotations
from typing import overload

@overload
def foo(x: int) -> None: ...
@overload
def foo(a: str, /) -> None: ...

def foo(*args: int | str, **kw: int) -> None:
pass
[builtins fixtures/tuple.pyi]

[case testTypeCheckOverloadWithImplTooSpecificRetType]
from typing import overload, Any

Expand Down
Loading