2018-12-11 13:50:56 -07:00
|
|
|
import inspect
|
|
|
|
from opcode import opname
|
|
|
|
|
|
|
|
|
|
|
|
class NameNotFound(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def get_var_name(depth=2):
|
|
|
|
frame = inspect.currentframe()
|
|
|
|
for _ in range(depth):
|
|
|
|
frame = frame.f_back
|
|
|
|
|
|
|
|
code = frame.f_code
|
|
|
|
call_index = frame.f_lasti
|
|
|
|
call_opc = opname[code.co_code[call_index]]
|
2018-12-12 19:20:00 -07:00
|
|
|
if call_opc not in ("CALL_FUNCTION", "CALL_FUNCTION_KW", "CALL_FUNCTION_EX", "CALL_METHOD"):
|
2018-12-11 13:50:56 -07:00
|
|
|
return None
|
|
|
|
|
|
|
|
index = call_index + 2
|
|
|
|
while True:
|
|
|
|
opc = opname[code.co_code[index]]
|
|
|
|
if opc in ("STORE_NAME", "STORE_ATTR"):
|
|
|
|
name_index = int(code.co_code[index + 1])
|
|
|
|
return code.co_names[name_index]
|
|
|
|
elif opc == "STORE_FAST":
|
|
|
|
name_index = int(code.co_code[index + 1])
|
|
|
|
return code.co_varnames[name_index]
|
|
|
|
elif opc == "STORE_DEREF":
|
|
|
|
name_index = int(code.co_code[index + 1])
|
|
|
|
return code.co_cellvars[name_index]
|
|
|
|
elif opc in ("LOAD_GLOBAL", "LOAD_ATTR", "LOAD_FAST", "LOAD_DEREF",
|
|
|
|
"DUP_TOP", "BUILD_LIST"):
|
|
|
|
index += 2
|
|
|
|
else:
|
|
|
|
raise NameNotFound
|