2

I've been using python-aspectlib to weave an aspect to certain methods - unfortunately this changes the methods signature to Argspec(args=[], varargs='args', keywords='kwargs', default=None), which creates problems when working with libraries that depend on inspect returning the proper signature(s).

Is there a way to use python-aspectlib without changing a method's signature? If not, are there other python aspect libraries that can do this?

I've looked at the decorator module, which explicitly mentions the problem of changing a method signature: http://micheles.googlecode.com/hg/decorator/documentation.html#statement-of-the-problem , but I was hoping to find a solution where I don't need to modify the methods I want to weave (since they are part of a third party library).

I'm using python 2.7.6

jfs
  • 399,953
  • 195
  • 994
  • 1,670
Martin
  • 138
  • 6
  • 1
    if `aspectlib` is an open-source library; submit a patch that enables the preserving of function signatures. Related: [How you implemented your Python decorator is wrong](https://github.com/GrahamDumpleton/wrapt/tree/master/blog) – jfs Oct 27 '14 at 13:16
  • It looks like before Python 3.3 you had to use `eval()` to set the correct function signature (as the `decorator` module does). In Python 3.3+ `wrapper.__signature__` is supported explicitly, [see PEP 362](http://legacy.python.org/dev/peps/pep-0362/). – jfs Oct 27 '14 at 13:45
  • 1
    This may help when you need to implement it yourself: http://stackoverflow.com/questions/23973783/python-decorator-with-arguments-of-decorated-function – User Oct 27 '14 at 13:52
  • aspectlib is an open source library - unfortunately my python knowledge isn't (yet) good enough to understand what they're doing (or actually patching it). Thanks for the links, they were very helpful. – Martin Oct 28 '14 at 14:57

1 Answers1

0

I've managed to 'fix' this for my specific use case with the following piece of code:

from decorator import decorator
from Module1 import Class1
from Module2 import Class2

def _my_decorator(func, *args, **kwargs):
    #add decorator code here
    return func(*args, **kwargs)


def my_decorator(f):
    return decorator(_my_decorator, f)

methods_to_decorate = [
    'Class1.method1',
    'Class2.method2',
    ]

for method in methods_to_decorate:
    exec_str = method + '= my_decorator('+method+'.im_func)'
    exec(exec_str)

This probably doesn't handle all of the issues mentioned in the How you implement your Python decorator is wrong blog posts, but it full fills the criteria most important to me: correct method signatures.

Martin
  • 138
  • 6