Skip to content

Commit ae3accb

Browse files
committed
Fix overload handling with union types in signatures
Previously `None` was not considered as more precise than `Optional[x]`, which was obviously incorrect. Fixed the implementation of type precision checking to match the description, how that proper subtype checking works. Fixes the original example in #3295.
1 parent 058a8a6 commit ae3accb

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

mypy/subtypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,4 @@ def is_more_precise(t: Type, s: Type) -> bool:
720720
# Fall back to subclass check and ignore other properties of the callable.
721721
return is_proper_subtype(t.fallback, s)
722722
return is_proper_subtype(t, s)
723-
return sametypes.is_same_type(t, s)
723+
return is_proper_subtype(t, s)

mypy/test/testtypes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ def test_is_more_precise(self) -> None:
175175
assert_true(is_more_precise(fx.b, fx.anyt))
176176
assert_true(is_more_precise(self.tuple(fx.b, fx.a),
177177
self.tuple(fx.b, fx.a)))
178+
assert_true(is_more_precise(self.tuple(fx.b, fx.b),
179+
self.tuple(fx.b, fx.a)))
178180

179181
assert_false(is_more_precise(fx.a, fx.b))
180182
assert_false(is_more_precise(fx.anyt, fx.b))
181-
assert_false(is_more_precise(self.tuple(fx.b, fx.b),
182-
self.tuple(fx.b, fx.a)))
183183

184184
# is_proper_subtype
185185

test-data/unit/check-optional.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,18 @@ x: Optional[Union[int, str]]
596596
reveal_type(x) # E: Revealed type is 'Union[builtins.int, builtins.str, builtins.None]'
597597
y: Optional[Union[int, None]]
598598
reveal_type(y) # E: Revealed type is 'Union[builtins.int, builtins.None]'
599+
600+
[case testOverloadWithNoneAndOptional]
601+
from typing import overload, Optional
602+
603+
@overload
604+
def f(x: int) -> str: ...
605+
@overload
606+
def f(x: Optional[int]) -> Optional[str]: ...
607+
def f(x): return x
608+
609+
reveal_type(f(1))
610+
reveal_type(f(None))
611+
[out]
612+
main:9: error: Revealed type is 'builtins.str'
613+
main:10: error: Revealed type is 'Union[builtins.str, builtins.None]'

0 commit comments

Comments
 (0)