Skip to content

types overlap only if all type args match #9452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2020
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
6 changes: 3 additions & 3 deletions mypy/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ def _type_object_overlap(left: Type, right: Type) -> bool:
# Or, to use a more concrete example, List[Union[A, B]] and List[Union[B, C]]
# would be considered partially overlapping since it's possible for both lists
# to contain only instances of B at runtime.
Comment on lines 339 to 341
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this example I am wondering if the original behavior wasn't intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example only has a single type argument; I think the case with multiple args was just not considered.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stumbled a little on this too, unions are dealt with by the recursive call, about a hundred lines earlier in the function

for left_arg, right_arg in zip(left.args, right.args):
if _is_overlapping_types(left_arg, right_arg):
return True
if all(_is_overlapping_types(left_arg, right_arg)
for left_arg, right_arg in zip(left.args, right.args)):
return True

return False

Expand Down
22 changes: 22 additions & 0 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -5151,3 +5151,25 @@ 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]

[case testOverloadTwoTypeArgs]
from typing import Generic, overload, TypeVar, Any

T1 = TypeVar("T1")
T2 = TypeVar("T2")

class A: ...
class B: ...
class G(Generic[T1, T2]): ...

@overload
def f1(g: G[A, A]) -> A: ...
@overload
def f1(g: G[A, B]) -> B: ...
def f1(g: Any) -> Any: ...

@overload
def f2(g: G[A, Any]) -> A: ... # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def f2(g: G[A, B], x: int = ...) -> B: ...
def f2(g: Any, x: int = ...) -> Any: ...