Skip to content

Commit 5dc8dce

Browse files
committed
Don't write constructor cache without strict optional
1 parent e633140 commit 5dc8dce

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

mypy/typeops.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
208208
fallback=named_type("builtins.function"),
209209
)
210210
result: FunctionLike = class_callable(sig, info, fallback, None, is_new=False)
211-
if allow_cache:
211+
if allow_cache and state.strict_optional:
212212
info.type_object_type = result
213213
return result
214214

@@ -230,7 +230,9 @@ def type_object_type(info: TypeInfo, named_type: Callable[[str], Instance]) -> P
230230
assert isinstance(method.type, FunctionLike) # is_valid_constructor() ensures this
231231
t = method.type
232232
result = type_object_type_from_function(t, info, method.info, fallback, is_new)
233-
if allow_cache:
233+
# Only write cached result is strict_optional=True, otherwise we may get
234+
# inconsistent behaviour because of union simplification.
235+
if allow_cache and state.strict_optional:
234236
info.type_object_type = result
235237
return result
236238

test-data/unit/check-classes.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9273,3 +9273,19 @@ class Bar:
92739273
[file foo.py]
92749274
class Bar:
92759275
...
9276+
9277+
[case testConstructorWithoutStrictOptionalNoCache]
9278+
import mod
9279+
a = mod.NT(x=None) # OK
9280+
9281+
[file typ.py]
9282+
from typing import NamedTuple, Optional
9283+
NT = NamedTuple("NT", [("x", Optional[str])])
9284+
9285+
[file mod.py]
9286+
# mypy: no-strict-optional
9287+
from typ import NT
9288+
9289+
def f() -> NT:
9290+
return NT(x='')
9291+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)