[Python-Dev] Proposed tweaks to functools.wraps

Steven D'Aprano steve at pearwood.info
Wed Aug 11 15:00:29 CEST 2010


On Wed, 11 Aug 2010 09:26:56 pm Simon Cross wrote:
> On Wed, Aug 11, 2010 at 4:39 AM, Benjamin Peterson 
<benjamin at python.org> wrote:
> > Namespace conflict with what? I would prefer "wraps" unless it's
> > standardized as a behavior for all decorators.
>
> Having the original function available as __wrapped__ would be really
> cool, although I'm not quite sure what the behaviour should be in
> corner cases like:
>
> * The decorator returns the original function (I suppose a reference
> to itself is okay?)

There's no reason why a function can't have an attribute that refers to 
the function itself. It works fine:

>>> def f():
...     return f.__wrapped__
...
>>> f.__wrapped__ = f
>>>
>>> f() is f
True

But in the case of a decorator returning the original function, the 
point is moot. If the original function is returned, then it hasn't 
been decorated at all, so there shouldn't be a __wrapped__ attribute 
added:

def decorator(func):
    if not __debug__:
        # Return undecorated original.
        return func  
    @wraps(func)
    def inner(*args):
        print args
        return func(*args)
    return inner



> * The decorator returns the a function that is already decorating
> something else.

That shouldn't make any difference. Given:

@wraps(f)
def func(*args):
    do_something()
    return f(*args)

then func.__wrapped__ gives f. If f itself wraps (say) g, and g wraps h, 
then you have:

func.__wrapped__ => f
func.__wrapped__.__wrapped__ => g
func.__wrapped__.__wrapped__.__wrapped__ => h

and so on, until you reach a function that doesn't wrap anything and 
doesn't have a __wrapped__ attribute.


I'm +1 on the proposal.



-- 
Steven D'Aprano


More information about the Python-Dev mailing list