Skip to content

Commit 690c4d5

Browse files
author
Guido van Rossum
committed
For Optional[T] or T, infer the type T instead of Optional[T].
Fixes #1817, fixes #1733.
1 parent 746fe01 commit 690c4d5

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

mypy/checkexpr.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,13 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type:
10901090
mypy.checker.find_isinstance_check(e.left, self.chk.type_map,
10911091
self.chk.typing_mode_weak())
10921092
elif e.op == 'or':
1093+
# Special case for `Optional[T] or T` -- this should infer T.
1094+
# If the type is a Union containing None, remove the None.
1095+
if isinstance(left_type, UnionType):
1096+
items = [i for i in left_type.items if not isinstance(i, NoneTyp)]
1097+
if len(items) < len(left_type.items):
1098+
left_type = UnionType.make_simplified_union(items)
1099+
10931100
_, right_map = \
10941101
mypy.checker.find_isinstance_check(e.left, self.chk.type_map,
10951102
self.chk.typing_mode_weak())

test-data/unit/check-optional.test

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,33 @@ def f(x: None) -> str: pass
175175
def f(x: int) -> int: pass
176176
reveal_type(f(None)) # E: Revealed type is 'builtins.str'
177177
reveal_type(f(0)) # E: Revealed type is 'builtins.int'
178+
179+
[case testOptionalTypeOrTypePlain]
180+
from typing import Optional
181+
def f(a: Optional[int]) -> int:
182+
return a or 0
183+
[out]
184+
185+
[case testOptionalTypeOrTypeTypeVar]
186+
from typing import Optional, TypeVar
187+
T = TypeVar('T')
188+
def f(a: Optional[T], b: T) -> T:
189+
return a or b
190+
[out]
191+
192+
[case testOptionalTypeOrTypeNoTriggerPlain]
193+
from typing import Optional
194+
def f(a: Optional[int], b: int) -> int:
195+
return b or a
196+
[out]
197+
main: note: In function "f":
198+
main:3: error: Incompatible return value type (got "Optional[int]", expected "int")
199+
200+
[case testOptionalTypeOrTypeNoTriggerTypeVar]
201+
from typing import Optional, TypeVar
202+
T = TypeVar('T')
203+
def f(a: Optional[T], b: T) -> T:
204+
return b or a
205+
[out]
206+
main: note: In function "f":
207+
main:4: error: Incompatible return value type (got "Optional[T]", expected "T")

0 commit comments

Comments
 (0)