Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis
import inspect
from functools import lru_cache
def nameof(_):
frame = inspect.currentframe().f_back
return _nameof(frame.f_code, frame.f_lasti)
@lru_cache
def _nameof(code, offset):
instructions = list(dis.get_instructions(code))
(current_instruction_index, current_instruction), = (
(index, instruction)
for index, instruction in enumerate(instructions)
if instruction.offset == offset
)
assert current_instruction.opname == "CALL_FUNCTION"
name_instruction = instructions[current_instruction_index - 1]
assert name_instruction.opname.startswith("LOAD_")
return name_instruction.argrepr
def test():
print(nameof(dis))
print(nameof(dis.get_instructions))
x = 1
print(nameof(x))
if __name__ == '__main__':
test()