Not with a full decompiler yet. I tested a real Python 3.14 .pyc: pycdc (Decompyle++) rejects it with Bad MAGIC!, and uncompyle6/decompyle3 don't run on 3.14 at all (they cap around 3.8–3.9). Full-source decompilers always lag a new CPython release. But 3.14 `.pyc` is still not private — the standard library's marshal + dis read the code object on *any* version, so the string literals and full logic come straight out. Try our in-browser .pyc Decompiler for supported versions, and use marshal + dis as the 3.14 bridge until pycdc catches up.
Python 3.14 is out, and a common question is already showing up in search: can you decompile a 3.14 .pyc back to source? Decompilers famously lag new Python releases, so I tested it properly — compiling a real .pyc on CPython 3.14 and running every tool against it. Here's exactly what works, what doesn't, and why shipping 3.14 bytecode still doesn't hide your code.
The test file
API_KEY = "sk-demo-314"def check(user, key):if key == "PRO-2026":return f"welcome {user}"return "denied"print(check("mithun", "PRO-2026"))
It has a hard-coded key and a license check — the two things people hope a .pyc hides. I compiled it with py_compile on Python 3.14; the file starts with the magic bytes 2b 0e 0d 0a (magic number 3627), which is what identifies it as 3.14 bytecode.
Full decompilers: not yet
The go-to tool for modern bytecode is pycdc (Decompyle++) — it's what our .pyc Decompiler runs in the browser. Pointed at the 3.14 file, it refuses to load it:
Bad MAGIC!Could not load file sample314.pyc
The pip-based decompilers are even further behind: uncompyle6 tops out around Python 3.8 and decompyle3 around 3.9 — neither runs on 3.14 bytecode at all. This isn't a bug; it's the normal lag. Every decompiler has to be taught each new version's magic number and opcodes by hand, so support for a brand-new release lands months later.
A .pyc's first four bytes are a version-specific magic number (3.14 = 3627). Bad MAGIC! simply means the decompiler doesn't recognize that version yet — not that the file is protected.
The method that works on any version: `marshal` + `dis`
A .pyc is just a 16-byte header followed by a marshal-serialized code object — the exact structure the interpreter runs. Python's own marshal and dis modules read it natively on *any* version, including one no decompiler supports yet. Running them (on Python 3.14) against the same file recovered everything that matters:
import marshal, diswith open("sample314.pyc", "rb") as f:f.read(16) # skip the 16-byte .pyc header (3.7+)code = marshal.load(f) # the module's code objectdis.dis(code) # full bytecode listingprint([c for c in code.co_consts if isinstance(c, str)])
string constants recovered:['sk-demo-314', 'mithun', 'PRO-2026', 'welcome ', 'denied']# dis excerpt (module level):LOAD_CONST 0 ('sk-demo-314')STORE_NAME 0 (API_KEY)LOAD_CONST 1 (<code object check ...>)MAKE_FUNCTIONSTORE_NAME 1 (check)
No decompiler, no matching interpreter version needed — the API key, the PRO-2026 license string, and the full control flow are all right there. You don't get clean .py back (you get bytecode plus constants), but for reading secrets or understanding logic it's usually enough, and it never hits a version wall. The interactive version of this is our Bytecode Disassembler, which now supports 3.14.
When will pycdc support 3.14?
There's no fixed date — decompiler support for a new CPython release typically arrives weeks to months after it ships, as maintainers map the new opcodes. pycdc (which powers our browser tool) has the broadest coverage and reaches new versions first, so it's the one to watch; uncompyle6/decompyle3 are effectively frozen at 3.8/3.9. Until full 3.14 support lands, marshal + dis is the reliable bridge. For .pyc files from 3.12 and earlier, our .pyc Decompiler already returns readable source today — see the full method comparison.
What this means if you ship 3.14 bytecode
"No decompiler supports my Python version yet" feels like protection, but the test shows it isn't: the strings and logic read straight out of the file with two standard-library calls. As with every other Python version, shipping .pyc is a cache format, not a lock. To actually protect 3.14 code:
- Obfuscate the source before compiling — rename identifiers and encrypt string literals with our free Python Obfuscator so even the recovered bytecode/constants are meaningless.
- Keep real secrets off the client — a hard-coded key survives in
co_constsverbatim; load it from the environment or a backend (protecting API keys in Python). - For the strongest bar, compile to a native module (Cython
.pyd/.soor a Nuitka binary) so there's no code object tomarshal.loadat all.
More on why bytecode isn't protection in can .pyc files be decompiled and is Python obfuscation secure?.
Decompile a .pyc in your browser — free
For Python 3.12 and earlier, our in-browser .pyc Decompiler returns readable source (pycdc via WebAssembly). Nothing is uploaded.
Open the .pyc DecompilerFree tools mentioned here
Related guides
Frequently asked questions
Can pycdc decompile Python 3.14?
Not yet. In testing, pycdc (Decompyle++) rejects a Python 3.14 .pyc with 'Bad MAGIC!' because it doesn't recognize the 3.14 magic number (3627) or its opcodes. Decompiler support always lags a new CPython release by weeks to months. pycdc has the broadest coverage and usually adds new versions first, so it's the one to watch — until then, use marshal + dis to read the bytecode.
How do I decompile a Python 3.14 .pyc file?
You can't get clean source from a full decompiler yet — pycdc says 'Bad MAGIC!' and uncompyle6/decompyle3 don't run on 3.14 (they cap at 3.8/3.9). But you can recover the strings and logic with the standard library: open the .pyc, skip the 16-byte header, marshal.load() the code object, then read co_consts and dis.dis(). This works on any Python version.
What does 'Bad MAGIC!' mean when decompiling a .pyc?
The first four bytes of a .pyc are a magic number identifying the exact CPython version that compiled it (3.14 = 3627). 'Bad MAGIC!' from pycdc means the decompiler doesn't support that version yet — not that the file is corrupt or protected. Use a tool that covers the version, or read the bytecode with marshal + dis in the meantime.
Does shipping a Python 3.14 .pyc protect my source code?
No. Even though no full decompiler supports 3.14 yet, a .pyc is just a marshaled code object — its string literals (including API keys) and control flow read straight out with the standard-library marshal and dis modules. To actually protect code, obfuscate the source before compiling, keep secrets off the client, or compile to a native .pyd/.so.
Which Python versions can be decompiled to source today?
Full-source decompilers cover most older versions: pycdc (and our in-browser .pyc Decompiler) handle roughly Python 2.x through 3.12 cleanly with partial 3.13, while uncompyle6/decompyle3 give near-perfect output up to 3.8/3.9. For 3.14 (and any version newer than the tools support), read the code object with marshal + dis instead.