Python 3.13 decompilation fails (MAKE_FUNCTION, CALL_KW, TO_BOOL) + Python 3.14 magic not recognized
Environment:
pycdc master branch at b428976 (April 2026)
- Target: Python 3.13.0 pyc files (magic
0x0df3 = 3571)
- Target: Python 3.14.2 pyc files (magic
0x0e2b = 3627)
- OS: Linux, gcc 14.2.0
Issue 1: Python 3.14 magic number missing
pycdas and pycdc both report Bad MAGIC! for Python 3.14 pyc files. Magic 0x0e2b (3627) is not in the magic detection table in data.cpp. The greenozon/pycdc fork has a py314 branch but it also lacks this magic entry (it has the same issue).
Issue 2: Python 3.13 MAKE_FUNCTION opcode mismatch
The 3.13 bytecode mapping (bytes/python_3_13.cpp) maps opcode 26 to MAKE_FUNCTION. However, CPython 3.13 final uses opcode 122 for MAKE_FUNCTION. The opcode numbering seems to be from a 3.13 pre-release where numbers differed.
Result: pycdc prints Unsupported opcode: MAKE_FUNCTION (122) and produces only imports/signatures with function bodies stubbed to pass.
Issue 3: CALL_KW (247) and TO_BOOL (123) unsupported on 3.13
Even when MAKE_FUNCTION is handled (e.g., on PR #579 branch), pycdc hits:
Unsupported opcode: CALL_KW (247) — used for click.option(...) and re.match(...) calls
Unsupported opcode: TO_BOOL (123) — used extensively for truthiness checks (if, and, or)
These are new Python 3.13 opcodes (PEP 709 and related changes) that need AST builder support.
Reproduction:
You can reproduce with the attached 3.13 pyc file. Build master, then:
$ pycdc cli.cpython-313.pyc
Unsupported opcode: MAKE_FUNCTION (122)
...
# WARNING: Decompyle incomplete
Where pycdas works fully:
$ pycdas cli.cpython-313.pyc
# Full disassembly output with correct opcodes
pycdas output confirming the real opcode numbers:
70 MAKE_FUNCTION ← opcode at offset 70
72 SET_FUNCTION_ATTRIBUTE 4 (MAKE_FUNCTION_ANNOTATIONS)
...
38 CALL 2
46 TO_BOOL ← opcode at offset 46
...
182 CALL_KW 12
The raw bytecode confirms these use CPython 3.13's actual opcode numbers, not pycdc's mapped 3.13 numbers.
Suggested fixes:
- Add magic
0x0e2b to data.cpp for Python 3.14, with corresponding bytes/python_3_14.cpp
- Update
bytes/python_3_13.cpp to use CPython 3.13 final's opcode numbering
- Add handlers in
ASTree.cpp for CALL_KW (converting to regular function call with keyword args) and TO_BOOL (converting to truthiness check, similar to existing boolean handling)
- Verify with a real 3.13 final pyc file rather than pre-release numbering
I can provide the test pyc files if helpful.
Python 3.13 decompilation fails (MAKE_FUNCTION, CALL_KW, TO_BOOL) + Python 3.14 magic not recognized
Environment:
pycdcmaster branch atb428976(April 2026)0x0df3= 3571)0x0e2b= 3627)Issue 1: Python 3.14 magic number missing
pycdasandpycdcboth reportBad MAGIC!for Python 3.14 pyc files. Magic0x0e2b(3627) is not in the magic detection table indata.cpp. Thegreenozon/pycdcfork has apy314branch but it also lacks this magic entry (it has the same issue).Issue 2: Python 3.13 MAKE_FUNCTION opcode mismatch
The 3.13 bytecode mapping (
bytes/python_3_13.cpp) maps opcode 26 toMAKE_FUNCTION. However, CPython 3.13 final uses opcode 122 forMAKE_FUNCTION. The opcode numbering seems to be from a 3.13 pre-release where numbers differed.Result:
pycdcprintsUnsupported opcode: MAKE_FUNCTION (122)and produces only imports/signatures with function bodies stubbed topass.Issue 3: CALL_KW (247) and TO_BOOL (123) unsupported on 3.13
Even when
MAKE_FUNCTIONis handled (e.g., on PR #579 branch),pycdchits:Unsupported opcode: CALL_KW (247)— used forclick.option(...)andre.match(...)callsUnsupported opcode: TO_BOOL (123)— used extensively for truthiness checks (if,and,or)These are new Python 3.13 opcodes (PEP 709 and related changes) that need AST builder support.
Reproduction:
You can reproduce with the attached 3.13 pyc file. Build master, then:
$ pycdc cli.cpython-313.pyc Unsupported opcode: MAKE_FUNCTION (122) ... # WARNING: Decompyle incompleteWhere
pycdasworks fully:$ pycdas cli.cpython-313.pyc # Full disassembly output with correct opcodespycdas output confirming the real opcode numbers:
The raw bytecode confirms these use CPython 3.13's actual opcode numbers, not pycdc's mapped 3.13 numbers.
Suggested fixes:
0x0e2btodata.cppfor Python 3.14, with correspondingbytes/python_3_14.cppbytes/python_3_13.cppto use CPython 3.13 final's opcode numberingASTree.cppforCALL_KW(converting to regular function call with keyword args) andTO_BOOL(converting to truthiness check, similar to existing boolean handling)I can provide the test pyc files if helpful.