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
Conversation
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class
This reverts commit 7ccff63.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
LGTM, but I have few minor suggestions.
|
Thanks @serhiy-storchaka! I applied your suggestions; would you mind taking another look? I discovered another interesting thing in the process: Python 3.13.0a1+ (heads/main:e5dfcc2b6e, Nov 15 2023, 17:23:51) [MSC v.1932 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from dataclasses import dataclass
>>> class Vanilla:
... def __set_name__(self, owner, name):
... self.name = name
...
>>> @dataclass
... class Foo:
... v: Vanilla = Vanilla()
...
>>> f = Foo()
>>> f.v.name
'v' |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
I am not sure that __set_name__ should be called for annotated fields.
Yes, I could be persuaded either way there. |
| setattr(nm_tpl, key, val) | ||
| try: | ||
| set_name = type(val).__set_name__ | ||
| except AttributeError: |
There was a problem hiding this comment.
Is it worth adding a test for the case where this yields some other exception (e.g. due to a weird metaclass)?
There was a problem hiding this comment.
Good catch. Seems like for normal classes, if any strange exception is raised when trying to lookup __set_name__, the interpreter just swallows it and moves on:
>>> class Meta(type):
... def __getattribute__(self, attr):
... if attr == "__set_name__":
... raise BaseException("NO")
...
>>> class VeryAnnoying(metaclass=Meta): pass
...
>>> class Foo:
... attr = VeryAnnoying()
...
>>>We should do the same here (though I don't want to swallow BaseExceptions, since that would catch KeyboardInterrupt, SystemExit, etc. -- I think I'll just use except Exception).
There was a problem hiding this comment.
Seems like for normal classes, if any strange exception is raised when trying to lookup
__set_name__, the interpreter just swallows it and moves on:
It looks like a bug. I do not think it should be reproduced here. It is better to fix it for normal classes.
There was a problem hiding this comment.
Okay, I opened #112453, and will revert the changes made here that reproduce the bug
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
0c9f2b9 to
3932d48
Compare
serhiy-storchaka
left a comment
There was a problem hiding this comment.
LGTM.
Few minor suggestions which you can ignore.
|
Thanks for the reviews! |
# Release 4.9.0 (December 9, 2023) This feature release adds `typing_extensions.ReadOnly`, as specified by PEP 705, and makes various other improvements, especially to `@typing_extensions.deprecated()`. There are no changes since 4.9.0rc1. # Release 4.9.0rc1 (November 29, 2023) - Add support for PEP 705, adding `typing_extensions.ReadOnly`. Patch by Jelle Zijlstra. - All parameters on `NewType.__call__` are now positional-only. This means that the signature of `typing_extensions.NewType.__call__` now exactly matches the signature of `typing.NewType.__call__`. Patch by Alex Waygood. - Fix bug with using `@deprecated` on a mixin class. Inheriting from a deprecated class now raises a `DeprecationWarning`. Patch by Jelle Zijlstra. - `@deprecated` now gives a better error message if you pass a non-`str` argument to the `msg` parameter. Patch by Alex Waygood. - `@deprecated` is now implemented as a class for better introspectability. Patch by Jelle Zijlstra. - Exclude `__match_args__` from `Protocol` members. Backport of python/cpython#110683 by Nikita Sobolev. - When creating a `typing_extensions.NamedTuple` class, ensure `__set_name__` is called on all objects that define `__set_name__` and exist in the values of the `NamedTuple` class's class dictionary. Patch by Alex Waygood, backporting python/cpython#111876. - Improve the error message when trying to call `issubclass()` against a `Protocol` that has non-method members. Patch by Alex Waygood (backporting python/cpython#112344, by Randolph Scholz).
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class (python#111876) Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class (python#111876) Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Closes #111874
NamedTupleclass namespaces don't have__set_name__called on them #111874