Skip to content

Commit bdbae49

Browse files
Port over the relevant tests
1 parent 385812a commit bdbae49

1 file changed

Lines changed: 98 additions & 1 deletion

File tree

Lib/test/test_typing.py

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from typing import Self, LiteralString
4242
from typing import TypeAlias
4343
from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs
44-
from typing import TypeGuard, TypeIs, NoDefault
44+
from typing import TypeGuard, TypeIs, NoDefault, NoExtraItems
4545
import abc
4646
import textwrap
4747
import typing
@@ -8770,6 +8770,32 @@ class ChildWithInlineAndOptional(Untotal, Inline):
87708770
class Wrong(*bases):
87718771
pass
87728772

8773+
def test_closed_values(self):
8774+
class Implicit(TypedDict): ...
8775+
class ExplicitTrue(TypedDict, closed=True): ...
8776+
class ExplicitFalse(TypedDict, closed=False): ...
8777+
8778+
self.assertIsNone(Implicit.__closed__)
8779+
self.assertIs(ExplicitTrue.__closed__, True)
8780+
self.assertIs(ExplicitFalse.__closed__, False)
8781+
8782+
def test_extra_items_class_arg(self):
8783+
class TD(TypedDict, extra_items=int):
8784+
a: str
8785+
8786+
self.assertIs(TD.__extra_items__, int)
8787+
self.assertEqual(TD.__annotations__, {'a': str})
8788+
self.assertEqual(TD.__required_keys__, frozenset({'a'}))
8789+
self.assertEqual(TD.__optional_keys__, frozenset())
8790+
8791+
class NoExtra(TypedDict):
8792+
a: str
8793+
8794+
self.assertIs(NoExtra.__extra_items__, NoExtraItems)
8795+
self.assertEqual(NoExtra.__annotations__, {'a': str})
8796+
self.assertEqual(NoExtra.__required_keys__, frozenset({'a'}))
8797+
self.assertEqual(NoExtra.__optional_keys__, frozenset())
8798+
87738799
def test_is_typeddict(self):
87748800
self.assertIs(is_typeddict(Point2D), True)
87758801
self.assertIs(is_typeddict(Union[str, int]), False)
@@ -9097,6 +9123,71 @@ class AllTheThings(TypedDict):
90979123
},
90989124
)
90999125

9126+
def test_closed_inheritance(self):
9127+
class Base(TypedDict, extra_items=ReadOnly[Union[str, None]]):
9128+
a: int
9129+
9130+
self.assertEqual(Base.__required_keys__, frozenset({"a"}))
9131+
self.assertEqual(Base.__optional_keys__, frozenset({}))
9132+
self.assertEqual(Base.__readonly_keys__, frozenset({}))
9133+
self.assertEqual(Base.__mutable_keys__, frozenset({"a"}))
9134+
self.assertEqual(Base.__annotations__, {"a": int})
9135+
self.assertEqual(Base.__extra_items__, ReadOnly[Union[str, None]])
9136+
self.assertIsNone(Base.__closed__)
9137+
9138+
class Child(Base, extra_items=int):
9139+
a: str
9140+
9141+
self.assertEqual(Child.__required_keys__, frozenset({'a'}))
9142+
self.assertEqual(Child.__optional_keys__, frozenset({}))
9143+
self.assertEqual(Child.__readonly_keys__, frozenset({}))
9144+
self.assertEqual(Child.__mutable_keys__, frozenset({'a'}))
9145+
self.assertEqual(Child.__annotations__, {"a": str})
9146+
self.assertIs(Child.__extra_items__, int)
9147+
self.assertIsNone(Child.__closed__)
9148+
9149+
class GrandChild(Child, closed=True):
9150+
a: float
9151+
9152+
self.assertEqual(GrandChild.__required_keys__, frozenset({'a'}))
9153+
self.assertEqual(GrandChild.__optional_keys__, frozenset({}))
9154+
self.assertEqual(GrandChild.__readonly_keys__, frozenset({}))
9155+
self.assertEqual(GrandChild.__mutable_keys__, frozenset({'a'}))
9156+
self.assertEqual(GrandChild.__annotations__, {"a": float})
9157+
self.assertIs(GrandChild.__extra_items__, NoExtraItems)
9158+
self.assertIs(GrandChild.__closed__, True)
9159+
9160+
class GrandGrandChild(GrandChild):
9161+
...
9162+
self.assertEqual(GrandGrandChild.__required_keys__, frozenset({'a'}))
9163+
self.assertEqual(GrandGrandChild.__optional_keys__, frozenset({}))
9164+
self.assertEqual(GrandGrandChild.__readonly_keys__, frozenset({}))
9165+
self.assertEqual(GrandGrandChild.__mutable_keys__, frozenset({'a'}))
9166+
self.assertEqual(GrandGrandChild.__annotations__, {"a": float})
9167+
self.assertIs(GrandGrandChild.__extra_items__, NoExtraItems)
9168+
self.assertIsNone(GrandGrandChild.__closed__)
9169+
9170+
def test_implicit_extra_items(self):
9171+
class Base(TypedDict):
9172+
a: int
9173+
9174+
self.assertIs(Base.__extra_items__, NoExtraItems)
9175+
self.assertIsNone(Base.__closed__)
9176+
9177+
class ChildA(Base, closed=True):
9178+
...
9179+
9180+
self.assertEqual(ChildA.__extra_items__, NoExtraItems)
9181+
self.assertIs(ChildA.__closed__, True)
9182+
9183+
def test_cannot_combine_closed_and_extra_items(self):
9184+
with self.assertRaisesRegex(
9185+
TypeError,
9186+
"Cannot combine closed=True and extra_items"
9187+
):
9188+
class TD(TypedDict, closed=True, extra_items=range):
9189+
x: str
9190+
91009191
def test_annotations(self):
91019192
# _type_check is applied
91029193
with self.assertRaisesRegex(TypeError, "Plain typing.Final is not valid as type argument"):
@@ -9326,6 +9417,12 @@ class A(typing.Match):
93269417
class B(typing.Pattern):
93279418
pass
93289419

9420+
def test_typed_dict_signature(self):
9421+
self.assertListEqual(
9422+
list(inspect.signature(TypedDict).parameters),
9423+
['typename', 'fields', 'total', 'closed', 'extra_items']
9424+
)
9425+
93299426

93309427
class AnnotatedTests(BaseTestCase):
93319428

0 commit comments

Comments
 (0)