Suppose I have a speak
function:
def speak():
print("moo")
I can disassemble it as one usually does, with dis.dis
:
>>> dis.dis(speak)
2 0 LOAD_GLOBAL 0 (print)
3 LOAD_CONST 1 ('moo')
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
But I want to destruct the code object associated with the speak
function into a sequence of instructions, and then compile these back.
With the help of dis.Bytecode
, I can get a sequence of dis.Instruction
s that represents the code object:
>>> bytecode = dis.Bytecode(speak)
>>> for instruction in bytecode:
... print(instruction)
...
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=2, is_jump_target=False)
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval='moo', argrepr="'moo'", offset=3, starts_line=None, is_jump_target=False)
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=6, starts_line=None, is_jump_target=False)
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=9, starts_line=None, is_jump_target=False)
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=10, starts_line=None, is_jump_target=False)
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=13, starts_line=None, is_jump_target=False)
Is there a straightforward way to compile these Instruction
objects into the original code object?
For instance, I'm looking for a compile_back
function that would take a sequence of instructions and output an exec
utable code object:
>>> code_object = compile_back(dis.get_instructions(speak))
>>> exec(code_object)
moo