This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Thomas701
Recipients Thomas701
Date 2021-08-20.12:07:01
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1629461221.25.0.480325774253.issue44961@roundup.psfhosted.org>
In-reply-to
Content
@classmethod defines a __wrapped__ attribute that always points to the inner most function in a decorator chain while functool's update_wrapper has been fixed to set the wrapper.__wrapped__ attribute after updating the wrapper.__dict__ (see https://bugs.python.org/issue17482) so .__wrapped__ points to the next decorator in the chain.
This results in inconsistency of the value of the.__wrapped__ attribute.

Consider this code:

from functools import update_wrapper


class foo_deco:
    def __init__(self, func):
        self._func = func
        update_wrapper(self, func)

    def __call__(self, *args, **kwargs):
        return self._func(*args, **kwargs)


class bar_deco:
    def __init__(self, func):
        self._func = func
        update_wrapper(self, func)

    def __call__(self, *args, **kwargs):
        return self._func(*args, **kwargs)


class Foo:
    @classmethod
    @foo_deco
    def bar_cm(self):
        pass

    @bar_deco
    @foo_deco
    def bar_bar(self):
        pass


print(Foo.bar_cm.__wrapped__)
# <function Foo.bar_cm at 0x7fb0254433a0>
print(Foo.bar_bar.__wrapped__)
# <__main__.foo_deco object at 0x7fb025445fd0>

# The foo_deco object is available on bar_cm this way though
print(Foo.__dict__['bar_cm'].__func__)
# <__main__.foo_deco object at 0x7fb025445fa0>

It would be more consistent if the fix that was applied to update_wrapper was ported to classmethod's construction (or classmethod could invoke update_wrapper directly, maybe). It's also worth noting that @staticmethod behaves the same and @property doesn't define a .__wrapped__ attribute. For @property, I don't know if this is by design or if it was just never ported, but I believe it would be a great addition just to be able to go down a decorator chain without having to special-case the code.
History
Date User Action Args
2021-08-20 12:07:01Thomas701setrecipients: + Thomas701
2021-08-20 12:07:01Thomas701setmessageid: <1629461221.25.0.480325774253.issue44961@roundup.psfhosted.org>
2021-08-20 12:07:01Thomas701linkissue44961 messages
2021-08-20 12:07:01Thomas701create