gh-111874: Call __set_name__ on objects that define the method inside a typing.NamedTuple class dictionary as part of the creation of that class (#111876)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Alex Waygood 2023-11-27 16:34:44 +00:00 committed by GitHub
parent ffe1b2d07b
commit 22e411e1d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 3 deletions

View file

@ -2743,11 +2743,26 @@ class NamedTupleMeta(type):
class_getitem = _generic_class_getitem
nm_tpl.__class_getitem__ = classmethod(class_getitem)
# update from user namespace without overriding special namedtuple attributes
for key in ns:
for key, val in ns.items():
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])
elif key not in _special:
if key not in nm_tpl._fields:
setattr(nm_tpl, key, val)
try:
set_name = type(val).__set_name__
except AttributeError:
pass
else:
try:
set_name(val, nm_tpl, key)
except BaseException as e:
e.add_note(
f"Error calling __set_name__ on {type(val).__name__!r} "
f"instance {key!r} in {typename!r}"
)
raise
if Generic in bases:
nm_tpl.__init_subclass__()
return nm_tpl