Skip to content

Commit 66d70c7

Browse files
authored
Fix refresh of functions with implicit optional arguments (#4993)
Type analysis would clear t.optional, so it wouldn't be there on future runs. This bug also apparently caused `__new__` methods to not pick up Optional from implicit optional arguments?
1 parent 257e3f3 commit 66d70c7

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

mypy/typeanal.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,14 @@ def __init__(self,
175175
self.aliases_used = set() # type: Set[str]
176176

177177
def visit_unbound_type(self, t: UnboundType) -> Type:
178+
typ = self.visit_unbound_type_nonoptional(t)
178179
if t.optional:
179-
t.optional = False
180180
# We don't need to worry about double-wrapping Optionals or
181181
# wrapping Anys: Union simplification will take care of that.
182-
return make_optional_type(self.visit_unbound_type(t))
182+
return make_optional_type(typ)
183+
return typ
184+
185+
def visit_unbound_type_nonoptional(self, t: UnboundType) -> Type:
183186
sym = self.lookup(t.name, t, suppress_errors=self.third_pass)
184187
if '.' in t.name:
185188
# Handle indirect references to imported names.

test-data/unit/check-classes.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2014,7 +2014,7 @@ class C:
20142014

20152015
x = C(foo=12)
20162016
x.a # E: "C" has no attribute "a"
2017-
C(foo='') # E: Argument "foo" to "C" has incompatible type "str"; expected "int"
2017+
C(foo='') # E: Argument "foo" to "C" has incompatible type "str"; expected "Optional[int]"
20182018
[builtins fixtures/__new__.pyi]
20192019

20202020
[case testConstructInstanceWithDynamicallyTyped__new__]

test-data/unit/fine-grained.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7123,3 +7123,15 @@ class Foo(a.I):
71237123
def g(self) -> None: pass
71247124
[out]
71257125
==
7126+
7127+
[case testImplicitOptionalRefresh1]
7128+
# flags: --strict-optional
7129+
from x import f
7130+
def foo(x: int = None) -> None:
7131+
f()
7132+
[file x.py]
7133+
def f() -> int: return 0
7134+
[file x.py.2]
7135+
def f() -> str: return '0'
7136+
[out]
7137+
==

0 commit comments

Comments
 (0)