I want to store the information returned by the dis function of the dis module in a structured way, using a dict, associating the mnemonics of each code of a line to the correspondent line number.
Note: Instruction is a subclass of _Instruction, defined in the dis module as a namedtuple.
Output:
disassembled_dict =
{
147: [ Instruction(opname='LOAD_FAST', opcode=124, arg=0, arg1=0, arg2=0, argval='x', argrepr='x', offset=0, starts_line=147, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=1, arg1=1, arg2=0, argval=1, argrepr='1', offset=3, starts_line=None, is_jump_target=False),
Instruction(opname='INPLACE_ADD', opcode=55, arg=None, arg1=None, arg2=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False),
Instruction(opname='STORE_FAST', opcode=125, arg=0, arg1=0, arg2=0, argval='x', argrepr='x', offset=7, starts_line=None, is_jump_target=False)
]
148: [ Instruction(opname='LOAD_FAST', opcode=124, arg=0, arg1=0, arg2=0, argval='x', argrepr='x', offset=10, starts_line=148, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=2, arg1=2, arg2=0, argval=2, argrepr='2', offset=13, starts_line=None, is_jump_target=False),
Instruction(opname='BINARY_POWER', opcode=19, arg=None, arg1=None, arg2=None, argval=None, argrepr='', offset=16, starts_line=None, is_jump_target=False),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, arg1=None, arg2=None, argval=None, argrepr='', offset=17, starts_line=None, is_jump_target=False)
]
}
**Code:** import dis def pretty_dispreatty_dis(function): fcode = function.__code__ ## call dis._get_instructions_bytes just the original dis function do disassembled_raw = [instruction for instruction in dis._get_instructions_bytes(fcode.co_code, fcode.co_varnames, fcode.co_names, fcode.co_consts, fcode.co_cellvars + fcode.co_freevars, dict(dis.findlinestarts(fcode)))] iter_instructions = iter(disassembled_raw) disassembled_dict = {} line_pack = [] while True: try: if not(line_pack): instruction = next(iter_instructions) line_pack.append(instruction) else: instruction = line_pack[0] if(instruction.starts_line): instruction = next(iter_instructions) while(instruction.starts_line is None): line_pack.append(instruction) instruction = next(iter_instructions) else: ## line_pack[0] is the first mnemonic of the code line ## line_pack[0].starts_line is the number of the code line disassembled_dict.update({line_pack[0].starts_line : (line_pack)}) line_pack = [instruction] else: disassembled_dict.update({line_pack[0].starts_line : (line_pack)}) line_pack = [] except StopIteration: ## append the last group print(line_pack) disassembled_dict.update({line_pack[0].starts_line : (line_pack)}) line_pack = [] break return disassembled_dict
The code works on Python 3.5, but I'm sure there are many chances to make it more idiomatic, cleaner and more readable...
Suggestions?