# -*- coding: utf-8 -*-
[docs]def disassemble(co, lasti=-1):
"""
Reimplementation of disassemble that returns a string.
Disassemble a code object.
"""
import opcode
import dis
code = co.co_code
labels = dis.findlabels(code)
linestarts = dict(dis.findlinestarts(co))
n = len(code)
i = 0
extended_arg = 0
free = None
str_list = []
def appendstr(msg):
str_list.append(msg)
while i < n:
c = code[i]
op = ord(c)
if i in linestarts:
if i > 0:
appendstr('')
appendstr("%3d" % linestarts[i])
else:
appendstr(' ')
if i == lasti:
appendstr('-->')
else:
appendstr(' ')
if i in labels:
appendstr('>>')
else:
appendstr(' ')
appendstr(repr(i).rjust(4))
appendstr(opcode.opname[op].ljust(20))
i = i + 1
if op >= opcode.HAVE_ARGUMENT:
oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
extended_arg = 0
i = i + 2
if op == opcode.EXTENDED_ARG:
extended_arg = oparg * 65536
appendstr(repr(oparg).rjust(5))
if op in opcode.hasconst:
appendstr('(' + repr(co.co_consts[oparg]) + ')')
elif op in opcode.hasname:
appendstr('(' + co.co_names[oparg] + ')')
elif op in opcode.hasjrel:
appendstr('(to ' + repr(i + oparg) + ')')
elif op in opcode.haslocal:
appendstr('(' + co.co_varnames[oparg] + ')')
elif op in opcode.hascompare:
appendstr('(' + opcode.cmp_op[oparg] + ')')
elif op in opcode.hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
appendstr('(' + free[oparg] + ')')
appendstr('')
output = '\n'.join(str_list)
return output