mirror of
https://github.com/python/cpython.git
synced 2025-10-06 15:11:58 +00:00
bpo-43923: Add support for generic typing.NamedTuple (#92027)
This commit is contained in:
parent
81fb3548be
commit
b04e02c57f
5 changed files with 66 additions and 4 deletions
|
@ -2764,7 +2764,12 @@ _special = frozenset({'__module__', '__name__', '__annotations__'})
|
|||
class NamedTupleMeta(type):
|
||||
|
||||
def __new__(cls, typename, bases, ns):
|
||||
assert bases[0] is _NamedTuple
|
||||
assert _NamedTuple in bases
|
||||
for base in bases:
|
||||
if base is not _NamedTuple and base is not Generic:
|
||||
raise TypeError(
|
||||
'can only inherit from a NamedTuple type and Generic')
|
||||
bases = tuple(tuple if base is _NamedTuple else base for base in bases)
|
||||
types = ns.get('__annotations__', {})
|
||||
default_names = []
|
||||
for field_name in types:
|
||||
|
@ -2778,12 +2783,18 @@ class NamedTupleMeta(type):
|
|||
nm_tpl = _make_nmtuple(typename, types.items(),
|
||||
defaults=[ns[n] for n in default_names],
|
||||
module=ns['__module__'])
|
||||
nm_tpl.__bases__ = bases
|
||||
if Generic in bases:
|
||||
class_getitem = Generic.__class_getitem__.__func__
|
||||
nm_tpl.__class_getitem__ = classmethod(class_getitem)
|
||||
# update from user namespace without overriding special namedtuple attributes
|
||||
for key in ns:
|
||||
if key in _prohibited:
|
||||
raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
|
||||
elif key not in _special and key not in nm_tpl._fields:
|
||||
setattr(nm_tpl, key, ns[key])
|
||||
if Generic in bases:
|
||||
nm_tpl.__init_subclass__()
|
||||
return nm_tpl
|
||||
|
||||
|
||||
|
@ -2821,9 +2832,7 @@ def NamedTuple(typename, fields=None, /, **kwargs):
|
|||
_NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {})
|
||||
|
||||
def _namedtuple_mro_entries(bases):
|
||||
if len(bases) > 1:
|
||||
raise TypeError("Multiple inheritance with NamedTuple is not supported")
|
||||
assert bases[0] is NamedTuple
|
||||
assert NamedTuple in bases
|
||||
return (_NamedTuple,)
|
||||
|
||||
NamedTuple.__mro_entries__ = _namedtuple_mro_entries
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue