depyo
Python bytecode decompiler for Python 1.0 through 3.15.
This is the Python port of depyo.js. The JavaScript version is the canonical implementation and is ~4–5× faster; this port exists so you can hack on decompilation logic in Python without a Node runtime.
Status
- Fixture parity with JS baseline: 1236 / 1236 byte-identical (100%) across the full fixture suite (Python 1.0–3.15) as of v1.2.4. Direct stdout-vs-stdout comparison, not just snapshot match.
- Port-only bugs: 0. Both ports also raise on the same 10 fixtures (shared opcode-handler gaps —
extractContextManager, Py2.7WITHtuple-unpack — tracked, not port defects). - Bytecode coverage: Python 1.0 through 3.15.
Install
pip install depyo
Or from source:
pip install -e .
Usage
depyo my_script.pyc
# → writes my_script.py next to the input
All JS CLI flags are supported (--asm, --debug, --raw, --dump, --stats, --strict, --py-version, --basedir, --out, --skip-source-gen, --skip-path, --marshal, --marshal-scan, --file-ext). Run depyo --help for the full list.
Speed
Measured across 1236 .pyc fixtures, 10 passes each:
| Runtime | ms/file | pyc/s | Relative |
|---|---|---|---|
| Node.js (V8) — depyo.js | 0.47 | 2143 | 1.0× |
| CPython 3.12 | 2.48 | 402 | 5.3× slower |
| PyPy 3.10 | 3.87 | 259 | 8.3× slower |
This port is ~4–5× slower than the JS original. Honest disclosure: if you need throughput, use the JS version. If you want to read and modify decompilation logic in idiomatic Python, use this one.
PyPy does not help — it's actually 35% slower than CPython on this workload. The fixtures are short-lived (fresh PycReader/PycDecompiler per file), so the JIT never warms up; hot paths are also heavy on hasattr/getattr/isinstance against polymorphic shapes, which PyPy doesn't specialize well.
Scope
Decompiles .pyc / .pyo from Python 1.0 through 3.15, including:
- All control flow (if/elif/else, while, for, try/except/finally, with, match/case)
- Comprehensions (list, set, dict, generator, async)
- Functions, classes, decorators, async def, coroutines
- PEP 695/696 generic type syntax (3.12+)
- PEP 750 template strings (3.14+)
License
MIT — see LICENSE.
Copyright (c) 2011–2026 Sergey Kuznetsov.
Metadata
Release files for depyo 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| depyo-1.3.0.tar.gz | 197.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| depyo-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 451.8 kB
Release files / depyo-1.3.0.tar.gz
| Download URL | depyo-1.3.0.tar.gz |
|---|---|
| Size | 197.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
88e558e517e41f21087786b4bb0fea7ea9876ef4177590c3e5f75ad5128639e4
|
|
BLAKE2b-256 checksum How to use checksums |
fdeb17870dfa6703c68c9cf0942456b3d2960d2d3d7543d9a6c0148e9bee4374
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|
Release files / depyo-1.3.0-py3-none-any.whl
| Download URL | depyo-1.3.0-py3-none-any.whl |
|---|---|
| Size | 254.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b144763a6141e5dc1bda70770ed02b36d970f821c68d15cb5f104393b2158fba
|
|
BLAKE2b-256 checksum How to use checksums |
e06b9b18b94c013f484bafeb67de7dce28fec6449b2ef2599b1c23f2658d79c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|