Skip to content

Commit 41733c4

Browse files
committed
Fix bug in overload compatibility checking
Discovered as part of python#14017
1 parent 428b172 commit 41733c4

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

mypy/subtypes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ def visit_overloaded(self, left: Overloaded) -> bool:
840840
found_match = True
841841
matched_overloads.add(left_item)
842842
possible_invalid_overloads.discard(left_item)
843+
break
843844
else:
844845
# If this one overlaps with the supertype in any way, but it wasn't
845846
# an exact match, then it's a potential error.

test-data/unit/check-classes.test

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,28 +3872,37 @@ class Super:
38723872
def foo(self, a: C) -> C: pass
38733873

38743874
class Sub(Super):
3875-
@overload # Fail
3875+
@overload
38763876
def foo(self, a: A) -> A: pass
38773877
@overload
38783878
def foo(self, a: B) -> C: pass # Fail
38793879
@overload
38803880
def foo(self, a: C) -> C: pass
3881+
3882+
class Sub2(Super):
3883+
@overload
3884+
def foo(self, a: B) -> C: pass # Fail
3885+
@overload
3886+
def foo(self, a: A) -> A: pass
3887+
@overload
3888+
def foo(self, a: C) -> C: pass
38813889
[builtins fixtures/classmethod.pyi]
38823890
[out]
3883-
tmp/foo.pyi:16: error: Signature of "foo" incompatible with supertype "Super"
3884-
tmp/foo.pyi:16: note: Superclass:
3885-
tmp/foo.pyi:16: note: @overload
3886-
tmp/foo.pyi:16: note: def foo(self, a: A) -> A
3887-
tmp/foo.pyi:16: note: @overload
3888-
tmp/foo.pyi:16: note: def foo(self, a: C) -> C
3889-
tmp/foo.pyi:16: note: Subclass:
3890-
tmp/foo.pyi:16: note: @overload
3891-
tmp/foo.pyi:16: note: def foo(self, a: A) -> A
3892-
tmp/foo.pyi:16: note: @overload
3893-
tmp/foo.pyi:16: note: def foo(self, a: B) -> C
3894-
tmp/foo.pyi:16: note: @overload
3895-
tmp/foo.pyi:16: note: def foo(self, a: C) -> C
38963891
tmp/foo.pyi:19: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
3892+
tmp/foo.pyi:24: error: Signature of "foo" incompatible with supertype "Super"
3893+
tmp/foo.pyi:24: note: Superclass:
3894+
tmp/foo.pyi:24: note: @overload
3895+
tmp/foo.pyi:24: note: def foo(self, a: A) -> A
3896+
tmp/foo.pyi:24: note: @overload
3897+
tmp/foo.pyi:24: note: def foo(self, a: C) -> C
3898+
tmp/foo.pyi:24: note: Subclass:
3899+
tmp/foo.pyi:24: note: @overload
3900+
tmp/foo.pyi:24: note: def foo(self, a: B) -> C
3901+
tmp/foo.pyi:24: note: @overload
3902+
tmp/foo.pyi:24: note: def foo(self, a: A) -> A
3903+
tmp/foo.pyi:24: note: @overload
3904+
tmp/foo.pyi:24: note: def foo(self, a: C) -> C
3905+
tmp/foo.pyi:25: error: Overloaded function signatures 1 and 2 overlap with incompatible return types
38973906

38983907
[case testTypeTypeOverlapsWithObjectAndType]
38993908
from foo import *

test-data/unit/check-selftype.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,34 @@ reveal_type(cast(A, C()).copy()) # N: Revealed type is "__main__.A"
128128

129129
[builtins fixtures/bool.pyi]
130130

131+
[case testSelfTypeOverrideCompatibility]
132+
from typing import overload, TypeVar, Generic
133+
134+
T = TypeVar("T")
135+
136+
class A(Generic[T]):
137+
@overload
138+
def f(self: A[int]) -> int: ...
139+
@overload
140+
def f(self: A[str]) -> str: ...
141+
def f(self): ...
142+
143+
class B(A[T]):
144+
@overload
145+
def f(self: A[int]) -> int: ...
146+
@overload
147+
def f(self: A[str]) -> str: ...
148+
def f(self): ...
149+
150+
class B2(A[T]):
151+
@overload
152+
def f(self: A[int]) -> int: ...
153+
@overload
154+
def f(self: A[str]) -> str: ...
155+
@overload
156+
def f(self: A[bytes]) -> bytes: ...
157+
def f(self): ...
158+
131159
[case testSelfTypeSuper]
132160
from typing import TypeVar, cast
133161

0 commit comments

Comments
 (0)