classification
Title: inspect.getsource does not work with decorated functions
Type: Stage:
Components: Library (Lib) Versions: Python 3.0, Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: christian.heimes, gpolo, michele_s, pitrou (4)
Priority: normal Keywords

Created on 2007-07-31 10:16 by michele_s, last changed 2008-02-07 20:10 by gpolo.

Files
File name Uploaded Description Edit Remove
inspect.py.diff gpolo, 2008-02-07 20:10
Messages (4)
msg32574 - (view) Author: Michele Simionato (michele_s) Date: 2007-07-31 10:16
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 
and not what would be more meaningful, i.e.
the string

"""
@identity_dec
def example(): 
    pass
"""

Of course one could argue that this is not a bug
(in a sense the inspect module is doing the right
thing) but still it is giving information which
is not very useful.

Looking at the guts of inspect.getsource, one discovers the origin 
of the problem: inspect.findsource is looking at the attribute 
.co_firstlineno of the decorated function code object.
Unfortunately .co_firstlineno is a read-only attribute, otherwise
it would be possibile to change functools.update_wrapper to set it to
the correct line number (i.e. the line where
the undecorated function is defined, -1). So 
I don't think you can fix this in current
Python, but it is something to keep in mind for Python 2.6 and 3.0. It should also manage classmethods/
staticmethods and other decorators not implemented
as closures.
msg57779 - (view) Author: Christian Heimes (christian.heimes) Date: 2007-11-23 09:13
I'm setting the target to 2.6 and 3.0. Maybe somebody can come up with a
sensible patch.
msg60062 - (view) Author: Antoine Pitrou (pitrou) Date: 2008-01-17 21:29
Rather than devising something specific to the co_firstlineno attribute,
why not have functools.update_wrapper add a "wrapped_func" attribute
pointing to the original function object? That way, each function
inspecting the decorated function would have the opportunity to walk the
decoration chain if it wants.
msg62177 - (view) Author: Guilherme Polo (gpolo) Date: 2008-02-07 20:10
I am attaching a patch that address this issue.
History
Date User Action Args
2008-02-07 20:10:28gpolosetfiles: + inspect.py.diff
nosy: + gpolo
messages: + msg62177
2008-01-17 21:29:40pitrousetnosy: + pitrou
messages: + msg60062
2007-11-23 09:13:58christian.heimessetnosy: + christian.heimes
title: inspect.getsource does not work with decorated functions -> inspect.getsource does not work with decorated functions
messages: + msg57779
versions: + Python 2.6, Python 3.0, - Python 2.5
2007-07-31 10:16:40michele_screate