@@ -985,7 +985,65 @@ A() + '' # E: No overload variant of "__add__" of "A" matches argument type "str
985985 # N: def __add__(self, A, /) -> int \
986986 # N: def __add__(self, int, /) -> int
987987
988+ [case testAllowOverrideOverloadSwapped]
989+ # https://github.com/python/mypy/issues/20720
990+ from foo import *
991+ [file foo.pyi]
992+ from typing import overload
993+
994+ def test_mutually_exclusive_types() -> None:
995+ # note: int and str are mutually exclusive types (@disjoint_base)
996+ class Parent:
997+ @overload
998+ def f(self, x: int) -> int: ...
999+ @overload
1000+ def f(self, x: str) -> str: ...
1001+ class Child(Parent):
1002+ @overload
1003+ def f(self, x: str) -> str: ...
1004+ @overload
1005+ def f(self, x: int) -> int: ...
1006+
1007+ def test_mutually_exclusive_signatures() -> None:
1008+ # the overload call-signatures are mutually exclusive,
1009+ # so swapping is safe even if intersections exist
1010+ class X: ...
1011+ class Y: ...
1012+ class A: ...
1013+ class B: ...
1014+
1015+ class Parent:
1016+ @overload
1017+ def f(self, *, x: X) -> A: ...
1018+ @overload
1019+ def f(self, *, y: Y) -> B: ...
1020+ class Child(Parent):
1021+ @overload
1022+ def f(self, *, y: Y) -> B: ...
1023+ @overload
1024+ def f(self, *, x: X) -> A: ...
1025+
1026+ def test_same_signature_and_return() -> None:
1027+ # swapping is safe if the return types are the same, even
1028+ # even if argument types overlap
1029+
1030+ class X: ...
1031+ class Y: ...
1032+
1033+ class Parent:
1034+ @overload
1035+ def f(self, x: X, /) -> None: ...
1036+ @overload
1037+ def f(self, y: Y, /) -> None: ...
1038+ class Child(Parent):
1039+ @overload
1040+ def f(self, y: Y, /) -> None: ...
1041+ @overload
1042+ def f(self, x: X, /) -> None: ...
1043+
1044+
9881045[case testOverrideOverloadSwapped]
1046+ # flags: --strict-overload-subtyping
9891047from foo import *
9901048[file foo.pyi]
9911049from typing import overload
@@ -1003,6 +1061,7 @@ class Child(Parent):
10031061 def f(self, x: int) -> int: ...
10041062
10051063[case testOverrideOverloadSwappedWithExtraVariants]
1064+ # flags: --strict-overload-subtyping
10061065from foo import *
10071066[file foo.pyi]
10081067from typing import overload
@@ -1040,6 +1099,7 @@ class Child3(Parent):
10401099 def f(self, x: bool) -> bool: ...
10411100
10421101[case testOverrideOverloadSwappedWithAdjustedVariants]
1102+ # flags: --strict-overload-subtyping
10431103from foo import *
10441104[file foo.pyi]
10451105from typing import overload
0 commit comments