I'm trying to decorate a fabric `WrappedCallableTask` object. The comment on
line 73 of `decorator.py` says `func` can be a class or callable, but not an
instance method. `WrappedCallableTask` objects are callable.
This seems to be because `self.signature` is only assigned for actual functions
(not callables). If I set it to an empty string instead, it works as expected.
Here's an interactive shell session demonstrating the problem.
In [1]: from fabric.api import task
In [2]: import decorator
In [3]: @decorator.decorator
...: def foo(func, *args, **kwargs):
...: print 'foo'
...: return func(*args, **kwargs)
...:
In [4]: def x():
...: print 'X'
...:
In [5]: x
Out[5]: <function __main__.x>
In [6]: x()
X
In [7]: foo(x)
Out[7]: <function __main__.x>
In [8]: foo(x)()
foo
X
In [9]: y = task(x)
In [10]: y
Out[10]: <fabric.tasks.WrappedCallableTask at 0x107171350>
# `y` is callable, just like `x`.
In [11]: y()
X
# But I can't decorate it with a decorator that has been created by
`decorator.decorator`.
In [12]: foo(y)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-c34da9d57b44> in <module>()
----> 1 foo(y)
<string> in foo(func)
/Users/tailee/.virtualenvs/ixcmembers/lib/python2.7/site-packages/decorator.pyc
in decorator(caller, func)
198 return FunctionMaker.create(
199 func, "return _call_(_func_, %(shortsignature)s)",
--> 200 evaldict, undecorated=func, __wrapped__=func)
201 else: # returns a decorator
202 if inspect.isclass(caller):
/Users/tailee/.virtualenvs/ixcmembers/lib/python2.7/site-packages/decorator.pyc
in create(cls, obj, body, evaldict, defaults, doc, module, addsource, **attrs)
182 signature = None
183 func = obj
--> 184 self = cls(func, name, signature, defaults, doc, module)
185 ibody = '\n'.join(' ' + line for line in body.splitlines())
186 return self.make('def %(name)s(%(signature)s):\n' + ibody,
/Users/tailee/.virtualenvs/ixcmembers/lib/python2.7/site-packages/decorator.pyc
in __init__(self, func, name, signature, defaults, doc, module, funcdict)
122 assert hasattr(self, 'name')
123 if not hasattr(self, 'signature'):
--> 124 raise TypeError('You are decorating a non function: %s' %
func)
125
126 def update(self, func, **kw):
TypeError: You are decorating a non function: <fabric.tasks.WrappedCallableTask
object at 0x107171350>
Original issue reported on code.google.com by t...@interaction.net.au on 24 Jun 2014 at 7:04
Original issue reported on code.google.com by
t...@interaction.net.au
on 24 Jun 2014 at 7:04