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 Dennis Sweeney
Recipients Dennis Sweeney, erezinman, kamilturek
Date 2021-03-22.17:09:32
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1616432972.74.0.660642078637.issue43010@roundup.psfhosted.org>
In-reply-to
Content
> other attributes will not be copied

The signature of wraps() is

    wraps(wrapped, assigned=('__module__', '__name__', '__qualname__', '__doc__', '__annotations__'), updated=('__dict__',))

Passing the updated=() will prevent the __dict__ from being updated, but those other attributes will still be assigned to:

    >>> from functools import wraps
    >>> def f(x: int) -> int:
    ...     "Square of a number"
    ...     return x ** 2
    ...
    >>> @wraps(f, updated=())
    ... def g(*args, **kwargs):
    ...     return f(*args, **kwargs)
    ...
    >>> help(g)
    Help on function f in module __main__:
    
    f(x: int) -> int
        Square of a number

> This is an interoperability bug

This is probably somewhat subjective, but I think the current behavior is okay: copy all of the attributes of the wrapped function into the wrapper. That's predictable, well-specified behavior, even if it has unexpected consequences in some situations -- I would say unusual situations, since 90% of the time I've seen @wraps used is in making custom decorators, where you really do mean to copy *all* of the attributes of the old function into the new one, and never think of the wrapped function again.

My thinking is also that to add a special case for abstract methods in functools would be to unnecessarily couple the functools module to implementation details of the ABC module. If someone using the ABC module wants to not update the __dict__ when using functools.wraps, there's already an easy switch for that, and it's completely orthogonal to what the __dict__ contains.

For an interesting precedent, @abstractclassmethod was created in https://bugs.python.org/issue5867 to solve a similar (I think) interoperability problem between @abstractmethod and @classmethod rather than adding a special case to @classmethod.

I would be interested in hearing if others want something to change about wraps().
History
Date User Action Args
2021-03-22 17:09:32Dennis Sweeneysetrecipients: + Dennis Sweeney, erezinman, kamilturek
2021-03-22 17:09:32Dennis Sweeneysetmessageid: <1616432972.74.0.660642078637.issue43010@roundup.psfhosted.org>
2021-03-22 17:09:32Dennis Sweeneylinkissue43010 messages
2021-03-22 17:09:32Dennis Sweeneycreate