Skip to content
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

bpo-43682: @staticmethod inherits attributes #25268

Merged
merged 3 commits into from
Apr 9, 2021
Merged

bpo-43682: @staticmethod inherits attributes #25268

merged 3 commits into from
Apr 9, 2021

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Apr 7, 2021

Static methods (@staticmethod) and class methods (@classmethod) now
inherit the method attributes (module, name, qualname,
doc, annotations) and have a new wrapped attribute.

Changes:

  • Add a repr() method to staticmethod and classmethod types.
  • Add tests on the @classmethod decorator.

https://bugs.python.org/issue43682

@vstinner
Copy link
Member Author

vstinner commented Apr 7, 2021

functools_wraps() call in cm_init() failed because Python didn't initialize PyClassMethod_Type type at startup. I created https://bugs.python.org/issue43770 to fix the issue: it's now fixed by df5dc1c

@vstinner
Copy link
Member Author

vstinner commented Apr 7, 2021

I chose the following representation:

$ ./python -q
>>> def func(): pass
... 
>>> staticmethod(func)
<staticmethod(<function func at 0x7f39e8152c50>)>
>>> classmethod(func)
<classmethod(<function func at 0x7f39e8152c50>)>

Static methods (@staticmethod) and class methods (@classmethod) now
inherit the method attributes (__module__, __name__, __qualname__,
__doc__, __annotations__) and have a new __wrapped__ attribute.

Changes:

* Add a repr() method to staticmethod and classmethod types.
* Add tests on the @classmethod decorator.
@vstinner
Copy link
Member Author

vstinner commented Apr 7, 2021

cc @serhiy-storchaka

@geryogam
Copy link
Contributor

@vstinner What’s this new __wrapped__ attribute? Is it the same as the existing __func__ attribute? If so, why did you introduce it?

@carljm
Copy link
Member

carljm commented May 21, 2023

What’s this new __wrapped__ attribute? Is it the same as the existing __func__ attribute? If so, why did you introduce it?

It's a standard attribute added by functools.wraps to wrapper functions allowing unwrapping back to the wrapped function (eg by inspect.unwrap). So it's generally useful for wrappers to set it.

@geryogam
Copy link
Contributor

@carljm Thanks, so I guess in this case it’s a documented duplicate of __func__ which is an undocumented attribute.

Comment on lines +721 to +724
PyObject *value = PyObject_GetAttr(wrapped, name);
if (value == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_Clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to use _PyObject_LookupAttr() here. See #106303.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants