Skip to content

Commit 72317c3

Browse files
ddfishergvanrossum
authored andcommitted
Fix PartialType-related crash in --strict-optional (#1992)
Some --strict-optional code previously assumed that the partial_types list could only contain PartialTypes. In some cases, it appears AnyType can also be part of that list. It's not entirely clear to me what causes this, but it looks like the correct solution is to be robust to the presence of other types in that list. Fixes #1948.
1 parent 7812a40 commit 72317c3

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

mypy/checker.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2247,7 +2247,8 @@ def leave_partial_types(self) -> None:
22472247
partial_types = self.partial_types.pop()
22482248
if not self.current_node_deferred:
22492249
for var, context in partial_types.items():
2250-
if experiments.STRICT_OPTIONAL and cast(PartialType, var.type).type is None:
2250+
if (experiments.STRICT_OPTIONAL and
2251+
isinstance(var.type, PartialType) and var.type.type is None):
22512252
# None partial type: assume variable is intended to have type None
22522253
var.type = NoneTyp()
22532254
else:

mypy/checkexpr.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ def try_infer_partial_type(self, e: CallExpr) -> None:
157157
var = cast(Var, e.callee.expr.node)
158158
partial_types = self.chk.find_partial_types(var)
159159
if partial_types is not None and not self.chk.current_node_deferred:
160-
partial_type = cast(PartialType, var.type)
161-
if partial_type is None or partial_type.type is None:
160+
partial_type = var.type
161+
if (partial_type is None or
162+
not isinstance(partial_type, PartialType) or
163+
partial_type.type is None):
162164
# A partial None type -> can't infer anything.
163165
return
164166
typename = partial_type.type.fullname()

test-data/unit/check-optional.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,18 @@ x = f # type: Callable[[], None]
315315
[case testOptionalCallable]
316316
from typing import Callable, Optional
317317
T = Optional[Callable[..., None]]
318+
319+
[case testAnyTypeInPartialTypeList]
320+
# options: check_untyped_defs
321+
def f(): ...
322+
323+
def lookup_field(name, obj):
324+
try:
325+
pass
326+
except:
327+
attr = f()
328+
else:
329+
attr = None
330+
[out]
331+
main: note: In function "lookup_field":
332+
main:10: error: Need type annotation for variable

0 commit comments

Comments
 (0)