I want to get the co_firstlineno for function in static way, The unwrapped function is ok, But if a method is wrapped, I can only get the lineno where the wrapper function is located.
md.py
import functools
def run(func):
@functools.wraps(func)
def warper(*args, **kwargs):
res = func()
return res
return warper
def func_unwrapper():
pass
@run
def func_with_wrapper():
pass
run.py
from importlib import util as module_util
import inspect
def load_moudle_by_path(path):
foo = module_util.spec_from_file_location('md', path)
md = module_util.module_from_spec(foo)
foo.loader.exec_module(md)
return md
def get_line():
md = load_moudle_by_path('md.py')
for name, o in inspect.getmembers(md):
if inspect.isfunction(o):
print('[{}]{}'.format(name, o.__code__.co_firstlineno))
get_line()
>>>
[func_unwrapper]10
[func_with_wrapper]4
[run]3
I see what you were hoping for, but the behaviour is expected behaviour.
func_with_wrapper
really is running the code at line 4, with the code at line 13 (which is what you were probably hoping for / expecting) only being called based on thefunc
parameter passed (thefunc_with_wrapper
argument).After your own research, finding
.__wrapped__
, whichfunctools
graciously adds, there's no need to add something similar yourself.Your original code will work, if you update:
Output: