python-aspectlib
python-aspectlib copied to clipboard
weave does not work with "generated" functions
In [1]: def foo_factory(foo_name):
def foo():
pass
foo.__name__ = foo_name
return foo
...:
In [2]: foo_func = foo_factory('foo_func')
In [3]: import aspectlib.contrib
In [4]: import aspectlib
In [5]: aspectlib.weave(foo_func, aspectlib.contrib.retry())
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-03b12c5d089d> in <module>()
----> 1 aspectlib.weave(foo_func, aspectlib.contrib.retry())
/home/yaroslavklyuyev/.virtualenvs/aiwona/lib/python3.4/site-packages/aspectlib/__init__.py in weave(target, aspects, **options)
474 path = deque(target.__qualname__.split('.')[:-1])
475 while path:
--> 476 owner = getattr(owner, path.popleft())
477 name = target.__name__
478 logdebug("@ patching %r (%s) as a property.", target, name)
AttributeError: 'function' object has no attribute '<locals>'
In [6]:
This issue can be solved by using dill.source.getname:
from demo import foo_func as custom_named_func
from dill.source import getname
from inspect import getmodule
module, object_name = getmodule(custom_named_func), getname(custom_named_func)
# results in <module 'demo' from '/some/path/demo.py'>, 'foo_func'
This can also be solved by setting __qualname__ in function factory. Maybe document it somewhere? Or better: raise exception that tells to set qualname when qualname contains '<locals>'
But still custom_named_func.__name__/custom_named_func.__qualname__ should match variable name or everything will fail
Yes indeed, this looks like a bug but there's no way to do this correctly. I could just skip the <locals> part but that don't guarantee correct behavior.
However, aspectlib supports weaving with no direct reference: weave('__main__.foo_func', contrib.retry) would work very well in your case and moves the responsibility of correctly figuring out what to patch in your app.
maybe raise exception that tells to use weave with string argument when qualname contains '<locals>'?
That's a great idea. I think a better error should be raised for all "weaving issues".