uncompyle6: Python Bytecode Decompiler
uncompyle6 is a cross-version Python bytecode decompiler. It allows you to convert Python bytecode (`.pyc` files or compiled function objects) back into human-readable Python source code. While the decompiler itself can run on modern Python versions (e.g., Python 3.6 to 3.12), it primarily supports decompiling bytecode from Python 2.x up to Python 3.8. The current version is 3.9.3, and it maintains an active release cadence, often aligning with major security conferences.
Common errors
-
ModuleNotFoundError: No module named 'xdis'
cause The essential `xdis` dependency was not installed or is not accessible in the current environment.fixEnsure `xdis` is installed: `pip install xdis` or reinstall uncompyle6 to ensure dependencies are resolved: `pip install uncompyle6 --upgrade`. -
uncompyle6.scanner.TokenError: Bad magic number for file ...
cause The `.pyc` file is either corrupted, from a significantly different Python version than `uncompyle6` expects, or is not a valid Python bytecode file.fixVerify the `.pyc` file's integrity and its original Python version. `uncompyle6` supports up to Python 3.8 bytecode. Using a `.pyc` from Python 3.9+ will likely cause this error. -
uncompyle6.scanner.TokenError: Unknown opcode: NNN (where NNN is a number)
cause The `.pyc` file contains opcodes introduced in a newer Python version (e.g., 3.9, 3.10, etc.) that `uncompyle6` does not yet have grammar rules for.fixThis indicates that `uncompyle6` does not support decompiling bytecode from that specific Python version. `uncompyle6` primarily supports up to Python 3.8. For newer versions, consider alternative decompilers or check for major uncompyle6 updates.
Warnings
- gotcha uncompyle6 can run on modern Python versions (e.g., 3.6-3.12), but it primarily supports decompiling bytecode up to Python 3.8. Attempting to decompile `.pyc` files from newer Python versions will likely result in errors or incorrect output.
- breaking The `xdis` library, a core dependency, frequently undergoes API changes. These changes can break `uncompyle6` if its bundled or required `xdis` version becomes incompatible with a newly installed or updated `xdis`.
- gotcha When Python code is compiled with optimization flags (`python -O` or `python -OO`), certain elements like docstrings and `assert` statements are removed from the bytecode. Decompiling such `.pyc` files will result in missing these elements.
Install
-
pip install uncompyle6
Imports
- decompile_file
from uncompyle6.decompile import decompile_file
- decompile
import uncompyle6.main uncompyle6.main.decompile(...)
Quickstart
import os
import py_compile
import sys
import textwrap
from pathlib import Path
from uncompyle6.decompile import decompile_file
# 1. Prepare: Create a dummy Python file and compile it to .pyc
temp_dir = Path("uncompyle6_quickstart_temp")
temp_dir.mkdir(exist_ok=True)
source_path = temp_dir / "my_module.py"
source_path.write_text(textwrap.dedent("""
def hello_world():
\"\"\"A simple greeting function.\"\"\"
print("Hello from uncompyle6!")
class MyUtil:
def __init__(self, name):
self.name = name
def greet(self):
return f"Greetings, {self.name}!"
"""))
# Compile the .py file to .pyc (ensures a standard .pyc structure)
py_compile.compile(str(source_path), cfile=str(source_path.with_suffix('.pyc')))
pyc_path = source_path.with_suffix('.pyc')
# 2. Decompile the .pyc file programmatically
try:
print(f"--- Decompiling {pyc_path.name} ---")
# decompile_file takes the input .pyc path and an output file-like object
decompile_file(pyc_path, sys.stdout)
print(f"--- Decompilation complete ---")
except Exception as e:
print(f"An error occurred during decompilation: {e}")
finally:
# 3. Cleanup temporary files and directory
if temp_dir.exists():
import shutil
shutil.rmtree(temp_dir)