-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-44863: In TypedDict allow inherit from Generic and preserve bases #27663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6cfdc5f
c022e44
2fa00b8
b829d8a
c5762df
4c5db0a
34189dd
0cfd637
5e808af
a2482ff
071c1b6
3ce517b
2f003e0
964f7d3
c3c0e51
d34c99e
cea66c4
0ed4326
b1fcd16
2905f29
afa5e51
94138f6
2572930
c2e1d8d
d3d9456
311852c
dc98753
9bed1d4
6c152e7
f88201b
6ea95df
80e9104
dbbb707
56b69e0
4a40825
4b50ae2
ecc7726
5b5a983
99a1430
79c2bb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1775,7 +1775,9 @@ def __init_subclass__(cls, *args, **kwargs): | |
if '__orig_bases__' in cls.__dict__: | ||
error = Generic in cls.__orig_bases__ | ||
else: | ||
error = Generic in cls.__bases__ and cls.__name__ != 'Protocol' | ||
error = (Generic in cls.__bases__ and | ||
cls.__name__ != 'Protocol' and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the existing code did this already, but checking the class name only seems wrong. Let me see if I can find a user-visible bug based on this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be written as |
||
type(cls) != _TypedDictMeta) | ||
if error: | ||
raise TypeError("Cannot inherit from plain Generic") | ||
if '__orig_bases__' in cls.__dict__: | ||
|
@@ -2848,14 +2850,19 @@ def __new__(cls, name, bases, ns, total=True): | |
Subclasses and instances of TypedDict return actual dictionaries. | ||
""" | ||
for base in bases: | ||
if type(base) is not _TypedDictMeta: | ||
if type(base) is not _TypedDictMeta and base is not Generic: | ||
raise TypeError('cannot inherit from both a TypedDict type ' | ||
'and a non-TypedDict base class') | ||
tp_dict = type.__new__(_TypedDictMeta, name, (dict,), ns) | ||
|
||
if any(issubclass(b, Generic) for b in bases): | ||
generic_base = (Generic,) | ||
else: | ||
generic_base = () | ||
|
||
tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) | ||
|
||
annotations = {} | ||
own_annotations = ns.get('__annotations__', {}) | ||
own_annotation_keys = set(own_annotations.keys()) | ||
msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" | ||
own_annotations = { | ||
n: _type_check(tp, msg, module=tp_dict.__module__) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Allow :class:`~typing.TypedDict` subclasses to also include | ||
:class:`~typing.Generic` as a base class in class based syntax. Thereby allowing | ||
the user to define a generic ``TypedDict``, just like a user-defined generic but | ||
with ``TypedDict`` semantics. |
Uh oh!
There was an error while loading. Please reload this page.