Skip to content

Commit d1ec354

Browse files
committed
Fix #3262: allow subtypes to define more overloads than their supertype
1 parent 665a810 commit d1ec354

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

mypy/subtypes.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,19 @@ def visit_overloaded(self, left: Overloaded) -> bool:
249249
return True
250250
return False
251251
elif isinstance(right, Overloaded):
252-
# TODO: this may be too restrictive
253-
if len(left.items()) != len(right.items()):
254-
return False
255-
for i in range(len(left.items())):
256-
if not is_subtype(left.items()[i], right.items()[i], self.check_type_parameter,
252+
# Ensure each overload in the left side is accounted for.
253+
sub_overloads = left.items()[:]
254+
while sub_overloads:
255+
left_item = sub_overloads[-1]
256+
for right_item in right.items():
257+
if is_subtype(left_item, right_item, self.check_type_parameter,
257258
ignore_pos_arg_names=self.ignore_pos_arg_names):
259+
sub_overloads.pop()
260+
break
261+
else:
262+
# One of the overloads was not present in the right side.
258263
return False
264+
259265
return True
260266
elif isinstance(right, UnboundType):
261267
return True

test-data/unit/check-classes.test

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,23 +1419,6 @@ class B(A):
14191419
[out]
14201420
tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A"
14211421

1422-
[case testOverloadedOperatorMethodOverrideWithSwitchedItemOrder]
1423-
from foo import *
1424-
[file foo.pyi]
1425-
from typing import overload, Any
1426-
class A:
1427-
@overload
1428-
def __add__(self, x: 'B') -> 'B': pass
1429-
@overload
1430-
def __add__(self, x: 'A') -> 'A': pass
1431-
class B(A):
1432-
@overload
1433-
def __add__(self, x: 'A') -> 'A': pass
1434-
@overload
1435-
def __add__(self, x: 'B') -> 'B': pass
1436-
[out]
1437-
tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A"
1438-
14391422
[case testReverseOperatorMethodArgumentType]
14401423
from typing import Any
14411424
class A: pass
@@ -2494,6 +2477,33 @@ reveal_type(f(BChild())) # E: Revealed type is 'foo.B'
24942477
[builtins fixtures/classmethod.pyi]
24952478
[out]
24962479

2480+
[case testSubtypeWithMoreOverloadsThanSupertypeSucceeds]
2481+
from foo import *
2482+
[file foo.pyi]
2483+
from typing import overload
2484+
2485+
2486+
class X: pass
2487+
class Y: pass
2488+
class Z: pass
2489+
2490+
2491+
class A:
2492+
@overload
2493+
def f(self, x: X) -> X: pass
2494+
@overload
2495+
def f(self, y: Y) -> Y: pass
2496+
2497+
class B(A):
2498+
@overload
2499+
def f(self, x: X) -> X: pass
2500+
@overload
2501+
def f(self, y: Y) -> Y: pass
2502+
@overload
2503+
def f(self, z: Z) -> Z: pass
2504+
[builtins fixtures/classmethod.pyi]
2505+
[out]
2506+
24972507
[case testTypeTypeOverlapsWithObjectAndType]
24982508
from foo import *
24992509
[file foo.pyi]

0 commit comments

Comments
 (0)