Skip to content

Commit b7d2b18

Browse files
committed
Fix false positive for overloaded methods with narrower returns
1 parent 0cc21d9 commit b7d2b18

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

mypy/checker.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,6 +2497,15 @@ def check_override(
24972497
# Use boolean variable to clarify code.
24982498
fail = False
24992499
op_method_wider_note = False
2500+
if isinstance(override, Overloaded) and isinstance(original, CallableType):
2501+
if not self.is_forward_op_method(name):
2502+
if all(is_subtype(item.ret_type, original.ret_type) for item in override.items):
2503+
return True
2504+
if isinstance(node, OverloadedFuncDef) and node.impl and node.impl.type:
2505+
impl_type = node.impl.type
2506+
if is_subtype(impl_type, original, ignore_pos_arg_names=True):
2507+
return True
2508+
25002509
if not is_subtype(override, original, ignore_pos_arg_names=True):
25012510
fail = True
25022511
elif isinstance(override, Overloaded) and self.is_forward_op_method(name):

test-data/unit/check-overloading.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,31 @@ class B(A):
11051105
def f(self, x: str) -> str: return ''
11061106
[out]
11071107

1108+
[case testOverloadedMethodWithNarrowerReturnTypes]
1109+
from typing import overload, Union, Optional
1110+
1111+
class A:
1112+
def view(self, x: Optional[int] = None) -> "A":
1113+
...
1114+
1115+
class B(A):
1116+
def view(self, x: Optional[int] = None) -> "B":
1117+
return B()
1118+
1119+
class C(A):
1120+
@overload # Should be allowed since B is a subtype of A
1121+
def view(self, x: int) -> B: ...
1122+
@overload # Should be allowed since C is a subtype of A
1123+
def view(self, x: None = None) -> "C": ...
1124+
def view(self, x: Optional[int] = None) -> Union[B, C]:
1125+
if x is None:
1126+
return C()
1127+
else:
1128+
return B()
1129+
1130+
reveal_type(C().view(None)) # N: Revealed type is "__main__.C"
1131+
reveal_type(C().view(5)) # N: Revealed type is "__main__.B"
1132+
11081133
[case testOverrideOverloadedMethodWithMoreSpecificArgumentTypes]
11091134
from foo import *
11101135
[file foo.pyi]

0 commit comments

Comments
 (0)