Skip to content

Instantly share code, notes, and snippets.

Created May 28, 2019 05:27
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Record call arguments by manually recording VM stack.
import dis
import sys
def g(x, y):
# Code that analyzes outer frame to get passed in arguments.
outer_frame = sys._getframe(1)
instructions = list(dis.get_instructions(outer_frame.f_code))
call_start_offset = None
call_end_offset = None
for index, instr in enumerate(instructions):
if instr.starts_line and instr.starts_line > outer_frame.f_lineno:
call_end_offset = index
# Assuming we already know the function name is 'g'.
if instr.argval == 'g':
call_start_offset = index
# Manually record top of stack
TOS = []
arguments_from_outside = []
for instr in instructions[call_start_offset:call_end_offset]:
if instr.opname == 'LOAD_NAME':
TOS.append((instr.argval, outer_frame.f_locals[instr.argval]))
elif instr.opname == 'LOAD_CONST':
TOS.append((instr.argval, None))
elif instr.opname == 'CALL_FUNCTION':
# Pops instr.arg elements from Top of stack, they are passed in arguments.
print(arguments_from_outside) # [('a', 1), (2, None)]
a = 1
print('Program ends')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment