-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
inspect.getsource does not work with decorated functions #45259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here is the issue: $ cat example.py
import functools # I am using Python 2.5 def identity_dec(func):
def wrapper(*args, **kw):
return func(*args, **kw)
return functools.update_wrapper(wrapper, func)
@identity_dec
def example():
pass >>> import inspect
>>> from example import example
>>> print inspect.getsource(example)
def wrapper(*args, **kw):
return func(*args, **kw) You get the source code of the closure """ Of course one could argue that this is not a bug Looking at the guts of inspect.getsource, one discovers the origin |
I'm setting the target to 2.6 and 3.0. Maybe somebody can come up with a |
Rather than devising something specific to the co_firstlineno attribute, |
I am attaching a patch that address this issue. |
I did not test the patch, but if it really addresses the issue, I don't see why such a simple fix would not be applied. Guilherme, Can you add unit tests? Also, the second chunk in your patch is just a style fix which is a distraction for reviewers. |
I don't think this patch is correct, because we don't know if the closure[0] is the wrapped function, consider the following case: def fun():
abc = 1
def fun2():
print(abc)
print(inspect.getsource(fun2)) In this case, the __closure__ of fun2 is [cell(1), ], the patch doesn't work. I think the behavior of inspect.getsource(arg) is no problem because it indeed gives the right source code of arg, no matter arg is a wrapper function or an original function. michele argues that the result is not meaningful, through in most case it seems reasonably because wrapper functions usually do litter valuable work, but it is not correct for all cases. What if a wrapper function does more valuable work than the wrapped function? In this case should getsouce() give the source code of wrapper function because it's more meaningful? The concept "wrapper" and "wrapped" should have no relation with its source code. I suggest you assign a special named attribute of all wrapper functions to its wrapped function yourself, something like "wrapped_function", and then you can walk through the wrapper chain to find the real source you want for each wrapper function. Then the stdard library's update_wrapper() and getsource() can remain unchanged. |
Hello. Attached patch which uses the new inspect.unwrap, added in http://hg.python.org/cpython/rev/2aa6c1e35b8a. |
New changeset ad9cc6124a19 by Yury Selivanov in branch 'default': |
Thanks for the bug report and patch! Committed to 3.5. |
This now leaves
>>> @contextmanager
... def func():
... yield
>>> inspect.getsource(func)
'@contextmanager\ndef func():\n yield\n'
>>>inspect.getsourcefile(func)
'C:\\Program Files\\Python 3.5\\lib\\contextlib.py' Should This is causing numpy/numpy#11639, but it's not clear if this is a bug or by design. |
I'd say yes. There's no point in getsourcefile returning the file location of the topmost decorator. Feel free to open a new issue and submit a PR to fix this! |
New issue opened at https://bugs.python.org/issue34305, along with a PR linked there. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: