Skip to content

Instantly share code, notes, and snippets.

@lrq3000
Last active November 11, 2020 19:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lrq3000/eda602434174e6635bfb to your computer and use it in GitHub Desktop.
Save lrq3000/eda602434174e6635bfb to your computer and use it in GitHub Desktop.
Recursive Python bytecode disassembler
import dis
import types
def getFuncByName(fname):
possibles = globals().copy()
possibles.update(locals())
f = possibles.get(fname)
if f:
return f
else:
return None
def get_code_object(obj, compilation_mode="exec"):
if isinstance(obj, (types.CodeType, types.ClassType, type)):
return obj
elif isinstance(obj, types.FrameType):
return obj.f_code
elif isinstance(obj, types.FunctionType):
return obj.__code__
elif isinstance(obj, str):
try:
return compile(obj, "<string>", compilation_mode)
except SyntaxError as error:
raise ValueError("syntax error in passed string")
else:
raise TypeError("get_code_object() can not handle '%s' objects" %
(type(obj).__name__,))
def _visit(obj, visitor, mode="exec", recurse=False):
obj = get_code_object(obj, mode)
visitor(obj)
if recurse:
if hasattr(obj, 'co_names'):
for fname in obj.co_names:
f = getFuncByName(fname)
#print(fname, f)
if f:
print('\n-> Recursing into %r %r:' % (fname, f))
_visit(f, visitor, mode, recurse)
def diss(obj, mode="exec", recurse=False):
_visit(obj, dis.dis, mode, recurse)
def ssc(obj, mode="exec", recurse=False):
_visit(obj, dis.show_code, mode, recurse)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment