I got a pretty weird behaviour with the decorator library which is explained in the next code:
from decorator import decorator
@decorator
def wrap(f, a, *args, **kwargs):
print 'Decorator:', a, args, kwargs
return f(a, *args, **kwargs)
def mywrap(f):
def new_f(a, *args, **kwargs):
print 'Home made decorator:', a, args, kwargs
return f(a, *args, **kwargs)
return new_f
@wrap
def funcion(a, b, *args, **kwargs):
pass
@mywrap
def myfuncion(a, b, *args, **kwargs):
pass
funcion(1, b=2)
myfuncion(1, b=2)
The execution of this script prints:
$ python /tmp/test.py
Decorator: 1 (2,) {}
Home made decorator: 1 () {'b': 2}
‘decorator’ hides the kwargs inside the args, how can I solve this without using a “home made” decorator.
Thanks.
Just because you call the function with
b=2does not makeba keyword argument;bis a positional argument in the original function. If there were no argument namedband you specifiedb=2, thenbwould become a keyword argument.decorator‘s behavior is actually the most correct; the wrapper it generates has the same signature asfuncion(), whereas the wrapper made by your “homemade” decorator does not havebas a named argument. The “homemade” wrapper “incorrectly” putsbinkwargsbecause the signature ofmyfuncion(), which makes it clear thatbis not a keyword arg, is hidden from the caller.Preserving the function signature is a feature, not a bug, in
decorator.