[issue21794] stack frame contains name of wrapper method, not that of wrapped method

Zachary Ware report at bugs.python.org
Wed Jun 18 22:56:57 CEST 2014


Zachary Ware added the comment:

I agree with Josh; I don't think there's any bug here.  To confirm, I expanded on your example, reproduced below.  Have a look at and play around with this, and if you still believe something is wrong, ask on python-list and the folks there should be able to help.  If you determine that there really is a bug, please reopen the issue.

"""
import functools
import inspect

def lineno():
    return inspect.getlineno(inspect.stack()[1][0])

try: # just to make it easy to see code and output together...
    with open(__file__) as file: data = file.read()
    print(data[:data.rfind("# output:") + 9])
except Exception:
    pass

print('#line {}: defining decorator'.format(lineno()))

def decorator(f):
    print('#  line {}: decorator called'.format(lineno()))
    print('#  line {}: defining inner'.format(lineno()))
    @functools.wraps(f)
    def inner(arg1, arg2):
        print('#    line {}: inner called, arg1 {} arg2 {}'.format(lineno(), arg1, arg2))
        for i, frame in enumerate(inspect.stack()):
            print("#      line {}: printed in inner, frame {}, name {}".format(lineno(), i, frame[3]))
        f(arg1 + 1 , arg2 + 1)

    print('#  line {}: printed in decorator, inner.__name__ == {}'.format(lineno(),inner.__name__))
    print('#  line {}: printed in decorator, f.__name__ == {}'.format(lineno(), f.__name__))
    return inner

print('#line {}: defining wrapped'.format(lineno()))

@decorator
def wrapped(warg1, warg2):
    print('#  line {}: wrapped called, warg1 {} warg2 {}'.format(lineno(), warg1, warg2))
    print("#  line {}: printed in wrapped, wrapped.__name__ == {}".format(lineno(), wrapped.__name__))
    stack = inspect.stack()
    for i, frame in enumerate(stack):
        print("#    line {}: printed in wrapped, frame {}, name {}".format(lineno(), i, frame[3]))

print('#line {}: Calling wrapped...'.format(lineno()))
wrapped(1,2)

print("#line {}: done".format(lineno()))

# output:

# expected output:
#line 13: defining decorator
#line 29: defining wrapped
#  line 16: decorator called
#  line 17: defining inner
#  line 25: printed in decorator, inner.__name__ == wrapped
#  line 26: printed in decorator, f.__name__ == wrapped
#line 39: Calling wrapped...
#    line 20: inner called, arg1 1 arg2 2
#      line 22: printed in inner, frame 0, name inner
#      line 22: printed in inner, frame 1, name <module>
#  line 33: wrapped called, warg1 2 warg2 3
#  line 34: printed in wrapped, wrapped.__name__ == wrapped
#    line 37: printed in wrapped, frame 0, name wrapped
#    line 37: printed in wrapped, frame 1, name inner
#    line 37: printed in wrapped, frame 2, name <module>
#line 42: done
"""

----------
nosy: +zach.ware
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue21794>
_______________________________________


More information about the Python-bugs-list mailing list