Skip to content

Commit 46e6aad

Browse files
bpo-46445: Cover multiple inheritance of TypedDict in test_typing (GH-30719)
(cherry picked from commit 65b88d5) Co-authored-by: Nikita Sobolev <[email protected]>
1 parent d548c87 commit 46e6aad

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

Lib/test/test_typing.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from typing import is_typeddict
2020
from typing import no_type_check, no_type_check_decorator
2121
from typing import Type
22-
from typing import NewType
2322
from typing import NamedTuple, TypedDict
2423
from typing import IO, TextIO, BinaryIO
2524
from typing import Pattern, Match
@@ -4302,6 +4301,93 @@ class Cat(Animal):
43024301
'voice': str,
43034302
}
43044303

4304+
def test_multiple_inheritance(self):
4305+
class One(TypedDict):
4306+
one: int
4307+
class Two(TypedDict):
4308+
two: str
4309+
class Untotal(TypedDict, total=False):
4310+
untotal: str
4311+
Inline = TypedDict('Inline', {'inline': bool})
4312+
class Regular:
4313+
pass
4314+
4315+
class Child(One, Two):
4316+
child: bool
4317+
self.assertEqual(
4318+
Child.__required_keys__,
4319+
frozenset(['one', 'two', 'child']),
4320+
)
4321+
self.assertEqual(
4322+
Child.__optional_keys__,
4323+
frozenset([]),
4324+
)
4325+
self.assertEqual(
4326+
Child.__annotations__,
4327+
{'one': int, 'two': str, 'child': bool},
4328+
)
4329+
4330+
class ChildWithOptional(One, Untotal):
4331+
child: bool
4332+
self.assertEqual(
4333+
ChildWithOptional.__required_keys__,
4334+
frozenset(['one', 'child']),
4335+
)
4336+
self.assertEqual(
4337+
ChildWithOptional.__optional_keys__,
4338+
frozenset(['untotal']),
4339+
)
4340+
self.assertEqual(
4341+
ChildWithOptional.__annotations__,
4342+
{'one': int, 'untotal': str, 'child': bool},
4343+
)
4344+
4345+
class ChildWithTotalFalse(One, Untotal, total=False):
4346+
child: bool
4347+
self.assertEqual(
4348+
ChildWithTotalFalse.__required_keys__,
4349+
frozenset(['one']),
4350+
)
4351+
self.assertEqual(
4352+
ChildWithTotalFalse.__optional_keys__,
4353+
frozenset(['untotal', 'child']),
4354+
)
4355+
self.assertEqual(
4356+
ChildWithTotalFalse.__annotations__,
4357+
{'one': int, 'untotal': str, 'child': bool},
4358+
)
4359+
4360+
class ChildWithInlineAndOptional(Untotal, Inline):
4361+
child: bool
4362+
self.assertEqual(
4363+
ChildWithInlineAndOptional.__required_keys__,
4364+
frozenset(['inline', 'child']),
4365+
)
4366+
self.assertEqual(
4367+
ChildWithInlineAndOptional.__optional_keys__,
4368+
frozenset(['untotal']),
4369+
)
4370+
self.assertEqual(
4371+
ChildWithInlineAndOptional.__annotations__,
4372+
{'inline': bool, 'untotal': str, 'child': bool},
4373+
)
4374+
4375+
wrong_bases = [
4376+
(One, Regular),
4377+
(Regular, One),
4378+
(One, Two, Regular),
4379+
(Inline, Regular),
4380+
(Untotal, Regular),
4381+
]
4382+
for bases in wrong_bases:
4383+
with self.subTest(bases=bases):
4384+
with self.assertRaisesRegex(
4385+
TypeError,
4386+
'cannot inherit from both a TypedDict type and a non-TypedDict',
4387+
):
4388+
class Wrong(*bases):
4389+
pass
4390+
43054391
def test_is_typeddict(self):
43064392
assert is_typeddict(Point2D) is True
43074393
assert is_typeddict(Union[str, int]) is False

0 commit comments

Comments
 (0)