[New-bugs-announce] [issue44961] @classmethod doesn't set __wrapped__ the same way as functool's update_wrapper

Thomas report at bugs.python.org
Fri Aug 20 08:07:01 EDT 2021


New submission from Thomas <thomas.d.mckay at gmail.com>:

@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.

----------
components: Extension Modules
messages: 399965
nosy: Thomas701
priority: normal
severity: normal
status: open
title: @classmethod doesn't set __wrapped__ the same way as functool's update_wrapper
type: behavior
versions: Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue44961>
_______________________________________


More information about the New-bugs-announce mailing list