-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
Objects in NamedTuple
class namespaces don't have __set_name__
called on them
#111874
Comments
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class
Your analysis is thorough and easy to follow. Nice work. |
Is it a bugfix or a new feature? Should it be backported? Should |
In my opinion, it's a bugfix, though I'd be okay with not backporting the fix if we consider it to be a risky fix. The fact that this hasn't come up until now demonstrates that not many people are putting custom descriptors in the namespaces of I initially encountered the bug when I tried to add a 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.
>>> import typing, functools
>>> class Foo(typing.NamedTuple):
... @functools.cached_property
... def bar(self): return True
...
>>> f = Foo()
>>> f.bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
f.bar
File "C:\Users\alexw\coding\cpython\Lib\functools.py", line 1003, in __get__
raise TypeError(
TypeError: Cannot use cached_property instance without calling __set_name__ on it.
|
I don't know; I'm interested in others' opinions here. For comparison's sake, it is the case that 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' |
It's arguably a bugfix, but it feels like too fundamental a change to backport it to earlier versions. I think we should change the behavior in 3.13 only. |
Sure, I've removed the backport labels from the PR. |
…de a `typing.NamedTuple` class dictionary as part of the creation of that class (#111876) Co-authored-by: Jelle Zijlstra <[email protected]>
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class (python#111876) Co-authored-by: Jelle Zijlstra <[email protected]>
…d inside a `typing.NamedTuple` class dictionary as part of the creation of that class (python#111876) Co-authored-by: Jelle Zijlstra <[email protected]>
Bug report
Bug description:
Generally speaking, any objects present in the namespace of a class
Foo
that define the special__set_name__
method will have that method called on them as part of the creation of the classFoo
. (__set_name__
is generally only used for descriptors, but can be defined on any class.)For example:
Descriptors inside
typing.NamedTuple
namespaces generally work the same way as in other class namespaces......but with one notable exception: they don't have
__set_name__
called on them!Why does this happen?
__set_name__
would normally be called on all members of a class dictionary during the class's creation. But theNamedTuple
classFoo
is created here:cpython/Lib/typing.py
Lines 2721 to 2723 in 97c4c06
And the
bar
attribute is only monkey-patched onto theFoo
class after the class has actually been created. This happens a few lines lower down intyping.py
, here:cpython/Lib/typing.py
Lines 2732 to 2733 in 97c4c06
__set_name__
isn't called onFoo.bar
as part of the creation of theFoo
class, because theFoo
class doesn't have abar
attribute at the point in time when it's actually being created.CPython versions tested on:
3.8, 3.11, 3.12, CPython main branch
Operating systems tested on:
Windows
Linked PRs
__set_name__
on objects that define the method inside atyping.NamedTuple
class dictionary as part of the creation of that class #111876The text was updated successfully, but these errors were encountered: