$ show zrax/pycdc
pycdc/pycdas is a C++11 command-line toolchain for reverse engineering CPython bytecode. pycdc decompiles compiled .pyc files back into human-readable Python source; pycdas emits a detailed bytecode disassembly (with options like --show-caches and --pycode-extra). Version coverage spans Python 1.0 (1994) through 3.13, with the correct opcode semantics selected from the .pyc magic number at load time. The entry points are pycdc.cpp and pycdas.cpp, which are thin CLIs over the pycxx static library that owns marshal-format parsing (pyc_object.cpp, pyc_numeric.cpp, pyc_string.cpp, pyc_sequence.cpp), code-object extraction (pyc_code.cpp), and interpreter version detection (pyc_module.cpp). It also supports decompiling raw marshalled code objects via -c -v <version>. Decompilation loads the code object and interprets its bytecode on a virtual stack machine (FastStack with history snapshots) inside ASTree.cpp, reconstructing structured control flow (loops, try/except, comprehensions, with-blocks) and lowering it into an ASTNode tree for source emission. Opcode semantics are maintained as an X-macro include (bytecode_ops.inl) with explicit version ranges, and per-version opcode-name maps live in bytes/python_*_*.cpp. The module boundaries cleanly separate binary I/O (endian-aware PycBuffer/PycFile streams), object marshalling, disassembly, AST construction, and printing - although the decompiler core itself is a dense, version-conditional megafile. QA is the project's strongest asset. Roughly 200 .pyc fixtures spanning every Python major release (plus an xfail set for known-unfixed cases) are checked by tests/run_tests.py, which compares decompiler output to expected output as token streams rather than exact text - tolerating cosmetic whitespace differences while still catching semantic regressions. Linux and Windows CI run the suite, and scripts/pymultic, Dockerfile.pybuild, and a collection of Autoconf modernization patches make it possible to rebuild ancient CPython releases to regenerate those fixtures. Recent commits cover Python 3.13 opcode support, and the repository is actively maintained. Caveats: the 25-year version matrix forces heavily conditional decompilation logic, some mutable global state exists in ASTree, and unknown or future-modified opcodes degrade to partial output with an 'Unsupported opcode' warning. For its niche, it is the most complete open-source CPython decompiler available.
The LLM identified 5 files worth highlighting for reuse:
Include-only X-macro table enumerating every CPython opcode with explicit first/last-version ranges (e.g., BINARY_ADD valid from Python 1.0 to 3.10). Zero internal dependencies; a new tool can drop it in to validate or label opcodes across the full CPython lineage, demonstrating the X-macro pattern for maintaining large versioned enums.
Header defining the macro contract that per-version files (bytes/python_1_0.cpp through bytes/python_3_13.cpp) instantiate into opcode-name/number lookup tables. The pattern cleanly factors per-version opcode differences into isolated translation units, making versioned bytecode support maintainable across 30+ interpreter releases; reusable for any multi-target binary tool.
Endian- and alignment-safe byte stream abstraction (PycData/PycBuffer/PycFile) that isolates .pyc container parsing from decompiler logic. Self-contained I/O layer with clean read primitives, directly extractable for any binary format parser that must handle little- and big-endian inputs.
Header-only fixed-capacity stack template with snapshot/history support, used to model CPython's evaluation stack during bytecode interpretation. Dependency-free and generic enough for any stack-machine analysis tool, including control-flow reconstruction and abstract interpretation.
Novel decompiler test harness that compares expected vs. actual output as Python token streams (via scripts/token_dump) rather than exact text: it catches semantic divergences while tolerating cosmetic formatting differences. Includes parallel execution and an xfail list for known-unfixed cases - a transferable pattern for testing any code generator or pretty-printer.