I have been playing with the dis
library to disassemble some Python source code, but I see that this does not recurse into functions or classes:
import dis
source_py = "test.py"
with open(source_py) as f_source:
source_code = f_source.read()
byte_code = compile(source_code, source_py, "exec")
dis.dis(byte_code)
All I see are entries such as:
54 456 LOAD_CONST 63 (<code object foo at 022C9458, file "test.py", line 54>)
459 MAKE_FUNCTION 0
462 STORE_NAME 20 (foo)
If the source file had a function foo()
, I could obviously add something like the following to the sourcefile:
dis.dis(foo)
I cannot figure out how to do this without changing the source file and executing it. I would like to be able to extract the pertinent bytes from the compiled byte_code
and pass them to dis.dis()
.
def sub_byte_code(byte_code, function_or_class_name):
sub_byte_code = xxxxxx
dis.dis(sub_byte_code)
I have considered wrapping the source code and executing dis.dis()
as follows but I do not wish to execute the script:
source_code_dis = "import dis\n%s\ndis.dis(foo)\n" % (source_code)
exec(source_code_dis)
Is there perhaps a trick to calling it? e.g. dis.dis(byte_code, recurse=True)
Import the file as a module and call dis.dis()
on that module (rather than the individual functions).
import dis
import test
dis.dis(test)
You can also do this from the command-line:
python -m dis test.py
Quoting from the documentation for dis.dis
:
For a module, it disassembles all functions.
Edit: As of python 3.7, dis.dis
is recursive.