Skip to main content
Reverse Engineering Module

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.

Advertisement
Compiled file (.pyc)

Drop a .pyc here, or click to choose

Runs in your browser. Max 8 MB.

No .pyc handy? Try one:

Samples are Python 3.9 bytecode — watch the source (variable names, strings and all) come straight back.

Decompiled Source
# Drop a .pyc above (or try a sample) — the recovered Python source appears here.

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.

You just watched code come back

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.

Add real licensing, free

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.

Before — license_check.py (the original source, for reference only)
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()
After — recovered from the .pyc by pycdc (real output)
# 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

pycdc — also called Decompyle++ — is a C++ decompiler that reconstructs readable .py source from compiled .pyc bytecode. This page runs the actual pycdc, compiled to WebAssembly, so you get pycdc's output directly in your browser with nothing to install or build. Because it's C++ (not pure Python like uncompyle6/decompyle3, which stop at Python 3.8–3.9), it covers much newer bytecode — clean for 3.0–3.12, partial for 3.13, and disassembly for 3.14.