Online pyc Decompiler (pycdc) — Decompile .pyc to Python
Decompile a compiled Python .pyc back to readable source with pycdc — in your browser via WebAssembly. Best-effort for 3.0–3.12, partial 3.13, disassembly 3.14.
Why use this tool?
Use the .pyc Decompiler to see exactly how much a compiled Python file gives away. Drop in a .pyc and it reconstructs readable source — variable names, string literals and the shape of the logic — using a decompiler engine compiled to WebAssembly that runs in your browser. Output is best-effort (review before trusting it), but it's the fastest way to prove to yourself that shipping .pyc is not protection.
Drop a .pyc here, or click to choose
Runs in your browser. Max 8 MB.
Samples are Python 3.9 bytecode — watch the source (variable names, strings and all) come straight back.
Recovers source for Python 1.x through ~3.12 (best on ≤3.11; very new versions may be partial), running entirely in your browser via WebAssembly. Output is best-effort — names and strings usually come back accurately, but control flow can be reconstructed incorrectly, so review and test recovered code before running it. Use it to inspect your own compiled Python and see how little a .pyc actually hides — then obfuscate so it can't be read back. See also: why .pyc isn't protection.
A license check inside a .pyc can be read — and patched out.
Obfuscation makes the source harder to read, but any check baked into the code can still be found and bypassed once someone decompiles it. Licers verifies each license against a server with Ed25519-signed responses and binds it to a device — so even a cracked, fully de-obfuscated copy still can't forge a valid license.
Tool facts
- Supported Python
- Python 2.x – 3.14 .pyc bytecode (pycdc)
- Input limit
- Max uploaded file: 8 MB
- Last reviewed
- 2026-09-03
What it can't do
- •Recover original comments or formatting — those aren't stored in a .pyc (docstrings usually survive, unless the file was compiled with -OO).
- •Guarantee correct output — pycdc is best-effort; control flow and optimized expressions can be reconstructed incorrectly, so review and test recovered code.
- •Decompile files encrypted or packed by tools like PyArmor.
About Python .pyc Decompiler
Most Python decompilers are limited: the popular pure-Python tools (uncompyle6, decompyle3) only cover up to Python 3.8–3.9 and won't even run on newer interpreters. This tool instead runs pycdc (Decompyle++), a C++ decompiler engine, compiled to WebAssembly so it works entirely in your browser. It recovers readable source for Python 3.0 through 3.12, returns a partial reconstruction for 3.13 (most of the source plus inlined disassembly for the newest opcodes), and shows the full disassembly for brand-new 3.14 bytecode — so you get usable output even on versions the pip-based decompilers can't touch at all.
Drop a .pyc file and you get recovered .py source back, including variable names and string literals. It's a best-effort reconstruction: names and constants usually come back accurately, but control flow and optimized expressions can be reconstructed incorrectly, so always review and test recovered code before running it. Where the newest bytecode can't be rebuilt, the engine inlines the raw disassembly. Because a .pyc gives up this much this easily, the takeaway is simple: to actually protect Python, obfuscate the source first so even the decompiled bytecode is unreadable.
Learn more: our Python .pyc decompiler guide explains how decompilation works, how to decompile a .pyc step by step walks through it with real output, and if Python won't load a .pyc at all, fix the "bad magic number" error with our tested magic-number table for Python 3.8–3.14.
See it decompile a real .pyc (tested)
Here's an actual run through the exact engine this page uses — pycdc (Decompyle++) compiled to WebAssembly. We took a small license-check script, compiled it to a Python 3.11 .pyc, and fed that .pyc (not the source) to the decompiler. This is the unedited output.
import sys
API_KEY = "sk-9f3a-PRO-2026"
def check_license(code):
valid = {"PRO-2026-XYZ", "TRIAL-7788"}
return code in valid
def main():
if len(sys.argv) < 2 or not check_license(sys.argv[1]):
print("Invalid or missing license key")
sys.exit(1)
print(f"Licensed. key={API_KEY}")
if __name__ == "__main__":
main()# Source Generated with Decompyle++
# File: in.pyc (Python 3.11)
import sys
API_KEY = 'sk-9f3a-PRO-2026'
def check_license(code):
valid = {
'PRO-2026-XYZ',
'TRIAL-7788'}
return code in valid
def main():
if not len(sys.argv) < 2 or check_license(sys.argv[1]):
print('Invalid or missing license key')
sys.exit(1)
print(f'''Licensed. key={API_KEY}''')
if __name__ == '__main__':
main()Everything sensitive comes back in plain text
The hard-coded API_KEY, both license codes, the function and variable names, and the structure of the logic all come straight back — from the compiled .pyc alone. That's the point: shipping .pyc (or freezing to an .exe, which just bundles .pyc) hides none of this. To actually protect the logic, obfuscate the source first so even the decompiled result is unreadable.
It's best-effort — review before you trust it
Look at the main() condition: pycdc reconstructed it as if not len(sys.argv) < 2 or check_license(...), but the original was if len(sys.argv) < 2 or not check_license(...) — those aren't logically equivalent, so the boolean was recovered *wrong*. Names, strings and overall structure are usually accurate, but control flow and optimized expressions can be rebuilt incorrectly. So recovered code is for reading and understanding — never run it without carefully reviewing and testing it against the original behavior. (3.13 comes back partially, 3.14 as disassembly.)
Frequently Asked Questions
Explore Other Tools
Python Bytecode Disassembler
Disassemble Python to CPython bytecode with the dis module — explore opcodes, code objects, jumps and constants. Runs in your browser.
Python Type Checker
Type-check your Python online with mypy — runs 100% in your browser via WebAssembly. Pick a target Python version (3.8–3.14) and strict mode.
Code to Flowchart
Turn Python code into a flowchart from the real AST — deterministic, no AI. Handles if, match, loops, try/except and async, with a control-flow-graph mode, unreachable-code highlighting, and Mermaid/SVG/PNG export.
requirements.txt → pyproject.toml Converter
Convert a requirements.txt (or requirements.in) into a pyproject.toml — runtime and dev dependency groups, with extras, version pins and environment markers preserved. Runs in your browser.