3 from opcode
import opname
6 __all__
= ["NameNotFound", "get_var_name", "get_src_loc"]
9 class NameNotFound(Exception):
13 def get_var_name(depth
=2):
14 frame
= inspect
.currentframe()
15 for _
in range(depth
):
19 call_index
= frame
.f_lasti
20 call_opc
= opname
[code
.co_code
[call_index
]]
21 if call_opc
not in ("CALL_FUNCTION", "CALL_FUNCTION_KW", "CALL_FUNCTION_EX", "CALL_METHOD"):
24 index
= call_index
+ 2
26 opc
= opname
[code
.co_code
[index
]]
27 if opc
in ("STORE_NAME", "STORE_ATTR"):
28 name_index
= int(code
.co_code
[index
+ 1])
29 return code
.co_names
[name_index
]
30 elif opc
== "STORE_FAST":
31 name_index
= int(code
.co_code
[index
+ 1])
32 return code
.co_varnames
[name_index
]
33 elif opc
== "STORE_DEREF":
34 name_index
= int(code
.co_code
[index
+ 1])
35 return code
.co_cellvars
[name_index
]
36 elif opc
in ("LOAD_GLOBAL", "LOAD_ATTR", "LOAD_FAST", "LOAD_DEREF",
37 "DUP_TOP", "BUILD_LIST"):
43 def get_src_loc(src_loc_at
=0):
44 # n-th frame: get_src_loc()
45 # n-1th frame: caller of get_src_loc() (usually constructor)
46 # n-2th frame: caller of caller (usually user code)
47 # Python returns the stack frames reversed, so it is enough to set limit and grab the very
48 # first one in the array.
49 tb
= traceback
.extract_stack(limit
=3 + src_loc_at
)
50 return (tb
[0].filename
, tb
[0].lineno
)