Skip to content

Instantly share code, notes, and snippets.

@sbp
Created November 23, 2013 17:53
Show Gist options
  • Save sbp/7617750 to your computer and use it in GitHub Desktop.
Save sbp/7617750 to your computer and use it in GitHub Desktop.
Disassemble a python code object as a string
def disassemble(co, lasti=-1):
"""Disassemble a code object."""
from dis import COMPILER_FLAG_NAMES, EXTENDED_ARG, HAVE_ARGUMENT, __all__, __builtins__, __cached__, __doc__, __file__, __initializing__, __loader__, __name__, __package__, _disassemble_bytes, _disassemble_str, _format_code_info, _have_code, _test, _try_compile, cmp_op, code_info, dis, disassemble, disco, distb, findlabels, findlinestarts, hascompare, hasconst, hasfree, hasjabs, hasjrel, haslocal, hasname, hasnargs, opmap, opname, pretty_flags, show_code, sys, types
output = []
def out(obj):
output.append(str(obj))
code = co.co_code
labels = findlabels(code)
linestarts = dict(findlinestarts(co))
n = len(code)
i = 0
extended_arg = 0
free = None
while i < n:
op = code[i]
if i in linestarts:
if i > 0:
out('\n')
out("%3d" % linestarts[i])
else:
out(' ')
if i == lasti: out('-->')
else: out(' ')
if i in labels: out('>>')
else: out(' ')
out(repr(i).rjust(4))
out(opname[op].ljust(20))
i = i+1
if op >= HAVE_ARGUMENT:
oparg = code[i] + code[i+1]*256 + extended_arg
extended_arg = 0
i = i+2
if op == EXTENDED_ARG:
extended_arg = oparg*65536
out(repr(oparg).rjust(5))
if op in hasconst:
out('(' + repr(co.co_consts[oparg]) + ')')
elif op in hasname:
out('(' + co.co_names[oparg] + ')')
elif op in hasjrel:
out('(to ' + repr(i + oparg) + ')')
elif op in haslocal:
out('(' + co.co_varnames[oparg] + ')')
elif op in hascompare:
out('(' + cmp_op[oparg] + ')')
elif op in hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
out('(' + free[oparg] + ')')
elif op in hasnargs:
out('(%d positional, %d keyword pair)'
% (code[i-2], code[i-1]))
out('\n')
return ''.join(output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment