__code__ attribute no longer copied/passed through in decorator>=5
bergtholdt opened this issue · 3 comments
Consider this simple example:
import decorator
def decor(func, *args, **kwargs):
return func(*args, **kwargs)
@decorator.decorator(decor)
def test(a, b, c=1, d=2):
pass
With decorator 4.4.2 I get:
test.__code__.co_argcount
4
>>> test.__code__.co_varnames
('a', 'b', 'c', 'd')
With decorator 5.0.9 I get:
>>> test.__code__.co_argcount
0
>>> test.__code__.co_varnames
('args', 'kw')
This breaks all my method decorators that I use with enthought traits library since they rely on func.code.co_argcount for trait change notification.
Is there a workaround I can do to my wrappers, without changing anything in the enthought traits library (like introducing inspect module there)?
Version 5 of the decorator module relies on the Signature object in the standard library which is a leaking abstraction and fails if one looks at low level objects like the __code__
objects. For the moment I would suggest you to stick with version 4. Otherwise you should define your decorators with the FunctionMaker class that still uses exec
and would pass the __code__
attribute, but it requires some work.
I am adding the following function in version 5.1:
def decoratorx(caller):
"""
A version of "decorator" implemented via "exec" and not via the
Signature object. Use this if you are want to preserve the `.__code__`
object properties (https://github.com/micheles/decorator/issues/129).
"""
def dec(func):
return FunctionMaker.create(
func,
"return _call_(_func_, %(shortsignature)s)",
dict(_call_=caller, _func_=func),
__wrapped__=func, __qualname__=func.__qualname__)
return dec
Then things will work as you want if you define
@decorator.decoratorx(decor)
def test(a, b, c=1, d=2):
pass
However, rather than using decoratorx
, you should fix your introspection routines to use inspect.Signature
without fiddling with the __code__
object.
For the record, decoratorx
is very helpful also with PySide6
signals. See GrahamDumpleton/wrapt#243 and/or https://stackoverflow.com/q/76596620/880783 if interested.