Skip to content

Commit bc686f5

Browse files
authored
Fix narrowing down types in deferred nodes (#4490)
Previously a partial type could be narrowed down to a bogus `Optional[Any]` type. Selectively switch narrowing down off in deferred nodes to work around the issue. Fixes #4488.
1 parent 302e0f4 commit bc686f5

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

mypy/checkexpr.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2595,7 +2595,11 @@ def bool_type(self) -> Instance:
25952595
def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type:
25962596
if literal(expr) >= LITERAL_TYPE:
25972597
restriction = self.chk.binder.get(expr)
2598-
if restriction:
2598+
# If the current node is deferred, some variables may get Any types that they
2599+
# otherwise wouldn't have. We don't want to narrow down these since it may
2600+
# produce invalid inferred Optional[Any] types, at least.
2601+
if restriction and not (isinstance(known_type, AnyType)
2602+
and self.chk.current_node_deferred):
25992603
ans = narrow_declared_type(known_type, restriction)
26002604
return ans
26012605
return known_type

test-data/unit/check-optional.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,3 +673,19 @@ class A:
673673
lambda: (self.y, x.a) # E: Cannot determine type of 'y'
674674
self.y = int()
675675
[builtins fixtures/isinstancelist.pyi]
676+
677+
[case testDeferredAndOptionalInferenceSpecialCase]
678+
def f() -> str:
679+
y
680+
x = None
681+
if int():
682+
x = ''
683+
if x is None:
684+
x = ''
685+
g(x)
686+
return x
687+
688+
def g(x: str) -> None: pass
689+
690+
y = int()
691+
[builtins fixtures/bool.pyi]

0 commit comments

Comments
 (0)