Search code examples
pythonpython-3.xbytecode

Why can't Python dis module disassembly this .pyc file?


I wrote a basic Python code in test.py

print("Hello World")

And then, I compiled with this code and generated .pyc file. I have now .py and .pyc file.

python -m compileall

Now, I use dis module for disassembly python bytecode but .pyc file not working while .py file working.

enter image description here

Why cannot a pyc bytecode file be dissamblied while py file can be dissamblied after compiled and bytecode is generated (.py -->(compile) --> bytecode) ?

My pyc file:

B

hAı]   ã               @   s   e d ƒ dS )zHello WorldN)Úprint© r   r   ú"C:\Users\ismet\Desktop\deneme\a.pyÚ<module>   s   

enter image description here

Thanks now.


Solution

  • While the dis.dis function supports both a source code string and a sequence of raw bytecode as input, the dis module as a main program, which is the way you're using it, supports only a file name of source code as input.

    Since the structure of a pyc file starts with 4 bytes of marshalling version number, 4 bytes of modification timestamp, and a dump of the raw bytecode from the marshal.dump method, per Ned Batchelder's excellent article, you can use marshal.load to restore the raw bytecode from the the pyc file after seeking the file position of index 8. However, this header size was really meant for Python 2 when Ned wrote the article. As @OndrejK. points out in the comment by referencing PEP-552, you would have to perform a f.seek(16) instead since Python 3.7, and f.seek(12) between Python 3.0 and Python 3.6:

    import dis
    import marshal
    
    with open('a.pyc', 'rb') as f:
        f.seek(16)
        dis.dis(marshal.load(f))