From 6110abd616184086d78f98c5593c374a6b41be45 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 18 Jan 2018 16:37:33 +0000 Subject: [PATCH] Fix narrowing down types in deferred nodes 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. --- mypy/checkexpr.py | 6 +++++- test-data/unit/check-optional.test | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index ecc4fd7b9279..833ddf2829aa 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2595,7 +2595,11 @@ def bool_type(self) -> Instance: def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type: if literal(expr) >= LITERAL_TYPE: restriction = self.chk.binder.get(expr) - if restriction: + # If the current node is deferred, some variables may get Any types that they + # otherwise wouldn't have. We don't want to narrow down these since it may + # produce invalid inferred Optional[Any] types, at least. + if restriction and not (isinstance(known_type, AnyType) + and self.chk.current_node_deferred): ans = narrow_declared_type(known_type, restriction) return ans return known_type diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index b7f6b047bb02..d7e550ecc212 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -673,3 +673,19 @@ class A: lambda: (self.y, x.a) # E: Cannot determine type of 'y' self.y = int() [builtins fixtures/isinstancelist.pyi] + +[case testDeferredAndOptionalInferenceSpecialCase] +def f() -> str: + y + x = None + if int(): + x = '' + if x is None: + x = '' + g(x) + return x + +def g(x: str) -> None: pass + +y = int() +[builtins fixtures/bool.pyi]