@@ -3685,14 +3685,35 @@ x["other"] = "a" # E: ReadOnly TypedDict key "other" TypedDict is mutated [typ
36853685[builtins fixtures/dict.pyi]
36863686[typing fixtures/typing-typeddict.pyi]
36873687
3688- [case testTypedDictReadOnlyDel ]
3688+ [case testTypedDictReadOnlyCreation ]
36893689from typing import ReadOnly, TypedDict
36903690
3691+ class TD(TypedDict):
3692+ x: ReadOnly[int]
3693+ y: int
3694+
3695+ # Ok:
3696+ x = TD({"x": 1, "y": 2})
3697+ y = TD(x=1, y=2)
3698+ z: TD = {"x": 1, "y": 2}
3699+
3700+ # Error:
3701+ x2 = TD({"x": "a", "y": 2}) # E: Incompatible types (expression has type "str", TypedDict item "x" has type "int")
3702+ y2 = TD(x="a", y=2) # E: Incompatible types (expression has type "str", TypedDict item "x" has type "int")
3703+ z2: TD = {"x": "a", "y": 2} # E: Incompatible types (expression has type "str", TypedDict item "x" has type "int")
3704+ [builtins fixtures/dict.pyi]
3705+ [typing fixtures/typing-typeddict.pyi]
3706+
3707+ [case testTypedDictReadOnlyDel]
3708+ from typing import ReadOnly, TypedDict, NotRequired
3709+
36913710class TP(TypedDict):
3692- key: ReadOnly[str]
3711+ required_key: ReadOnly[str]
3712+ optional_key: ReadOnly[NotRequired[str]]
36933713
36943714x: TP
3695- del x["key"] # E: Key "key" of TypedDict "TP" cannot be deleted
3715+ del x["required_key"] # E: Key "required_key" of TypedDict "TP" cannot be deleted
3716+ del x["optional_key"] # E: Key "optional_key" of TypedDict "TP" cannot be deleted
36963717[builtins fixtures/dict.pyi]
36973718[typing fixtures/typing-typeddict.pyi]
36983719
@@ -3710,10 +3731,35 @@ reveal_type(x.pop("key")) # E: Key "key" of TypedDict "TP" cannot be deleted \
37103731
37113732x.update({"key": "abc", "other": 1, "mutable": True}) # E: ReadOnly TypedDict keys ("key", "other") TypedDict are mutated
37123733x.setdefault("key", "abc") # E: ReadOnly TypedDict key "key" TypedDict is mutated
3734+ x.setdefault("other", 1) # E: ReadOnly TypedDict key "other" TypedDict is mutated
3735+ x.setdefault("mutable", False) # ok
37133736[builtins fixtures/dict.pyi]
37143737[typing fixtures/typing-typeddict.pyi]
37153738
3716- [case testTypedDictReadOnlyMutateStatements]
3739+ [case testTypedDictFromTypingExtensionsReadOnlyMutateMethods]
3740+ from typing_extensions import ReadOnly, TypedDict
3741+
3742+ class TP(TypedDict):
3743+ key: ReadOnly[str]
3744+
3745+ x: TP
3746+ x.update({"key": "abc"}) # E: ReadOnly TypedDict key "key" TypedDict is mutated
3747+ [builtins fixtures/dict.pyi]
3748+ [typing fixtures/typing-typeddict.pyi]
3749+
3750+ [case testTypedDictFromMypyExtensionsReadOnlyMutateMethods]
3751+ from mypy_extensions import TypedDict
3752+ from typing_extensions import ReadOnly
3753+
3754+ class TP(TypedDict):
3755+ key: ReadOnly[str]
3756+
3757+ x: TP
3758+ x.update({"key": "abc"}) # E: ReadOnly TypedDict key "key" TypedDict is mutated
3759+ [builtins fixtures/dict.pyi]
3760+ [typing fixtures/typing-typeddict.pyi]
3761+
3762+ [case testTypedDictReadOnlyMutate__ior__Statements]
37173763from typing_extensions import ReadOnly, TypedDict
37183764
37193765class TP(TypedDict):
@@ -3728,6 +3774,50 @@ x |= {"key": "a", "other": 1, "mutable": True} # E: ReadOnly TypedDict keys ("k
37283774[builtins fixtures/dict.pyi]
37293775[typing fixtures/typing-typeddict-iror.pyi]
37303776
3777+ [case testTypedDictReadOnlyMutate__or__Statements]
3778+ from typing_extensions import ReadOnly, TypedDict
3779+
3780+ class TP(TypedDict):
3781+ key: ReadOnly[str]
3782+ other: ReadOnly[int]
3783+ mutable: bool
3784+
3785+ x: TP
3786+ # These are new objects, not mutation:
3787+ x = x | {"mutable": True}
3788+ x = x | {"key": "a"}
3789+ x = x | {"key": "a", "other": 1, "mutable": True}
3790+ y1 = x | {"mutable": True}
3791+ y2 = x | {"key": "a"}
3792+ [builtins fixtures/dict.pyi]
3793+ [typing fixtures/typing-typeddict-iror.pyi]
3794+
3795+ [case testTypedDictReadOnlyMutateWithOtherDicts]
3796+ from typing import ReadOnly, TypedDict, Dict
3797+
3798+ class TP(TypedDict):
3799+ key: ReadOnly[str]
3800+ mutable: bool
3801+
3802+ class Mutable(TypedDict):
3803+ mutable: bool
3804+
3805+ class Regular(TypedDict):
3806+ key: str
3807+
3808+ m: Mutable
3809+ r: Regular
3810+ d: Dict[str, object]
3811+
3812+ # Creating new objects is ok:
3813+ tp: TP = {**r, **m}
3814+ tp1: TP = {**tp, **m}
3815+ tp2: TP = {**r, **m}
3816+ tp3: TP = {**tp, **r}
3817+ tp4: TP = {**tp, **d} # E: Unsupported type "Dict[str, object]" for ** expansion in TypedDict
3818+ [builtins fixtures/dict.pyi]
3819+ [typing fixtures/typing-typeddict.pyi]
3820+
37313821[case testTypedDictGenericReadOnly]
37323822from typing import ReadOnly, TypedDict, TypeVar, Generic
37333823
0 commit comments