Skip to content

weave does not work with "generated" functions #7

Open
@imposeren

Description

@imposeren
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

Activity

ionelmc

ionelmc commented on May 12, 2016

@ionelmc
Owner

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.

imposeren

imposeren commented on May 12, 2016

@imposeren
Author

maybe raise exception that tells to use weave with string argument when qualname contains '<locals>'?

ionelmc

ionelmc commented on May 12, 2016

@ionelmc
Owner

That's a great idea. I think a better error should be raised for all "weaving issues".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      weave does not work with "generated" functions · Issue #7 · ionelmc/python-aspectlib