Introduction
A .pyc file of this format holds one Python module compiled by
CPython 3.8 or 3.9, so that the next import can
skip compiling it. Python writes it to a __pycache__ folder beside the
source, with a name such as module.cpython-38.pyc, and only the release
that wrote it will load it.
The file is a 16-byte header followed by the module’s code object, written in
Python’s marshal format. The code object holds the instructions as
two-byte pairs, its constants and names, and a table that maps instructions to source
lines. Functions and classes defined in the module are further code objects inside its
constants.
A .pyc file dropped on any page of this site opens in the explorer,
which shows its structure, a disassembly and each code object.
Structure
All numbers are little-endian. There are two ways to fill the 8 bytes after the flags: most files record the source’s date and size, and a hash-based file records a hash of the source instead.
0magic: a 16-bit number, then0D 0A4 bytes4flags: 0 for a date check, 1 or 3 for a hash check4 bytes8source_mtime and source_size, or a source_hash8 bytes16code object of the module, in marshal formatvaries
Every code object holds its
instructions in
co_code and its line
numbers in co_lnotab.
What each release changed
The layout of the file is the same in both releases, apart from one field that
appeared during the 3.8 alphas. What changes is the instruction set and the meaning of
some co_flags bits. The numbers come from the magic number list in
CPython’s source.
| Release | Final magic | Changed |
|---|---|---|
| 3.8 | 3413 | co_posonlyargcount is added to every code object (magic 3410, PEP 570). Loops and try blocks are handled by the compiler (3400): SETUP_LOOP, SETUP_EXCEPT, BREAK_LOOP and CONTINUE_LOOP go, and BEGIN_FINALLY, CALL_FINALLY and POP_FINALLY arrive. END_ASYNC_FOR (3401) and ROT_FOUR are new. MAP_ADD now finds the value on top of the stack, key below it (3411). |
| 3.9 | 3425 | WITH_EXCEPT_START and RERAISE replace the older with and finally instructions (3421, 3422). LOAD_ASSERTION_ERROR (3420). IS_OP, CONTAINS_OP and JUMP_IF_NOT_EXC_MATCH take over the identity, membership and exception tests from COMPARE_OP (3423). LIST_EXTEND, SET_UPDATE, DICT_MERGE, DICT_UPDATE and LIST_TO_TUPLE replace the BUILD_*_UNPACK instructions (3424, 3425). The __future__ bits of co_flags move up: see flags. |
Telling it apart
The first two bytes, read as a little-endian number, are the magic number, and they
must be followed by 0D 0A. The explorer treats 3400 to 3429 as this
format: 55 0D 0D 0A is a final 3.8 file and 61 0D 0D 0A a
final 3.9 file. The magic number settles it alone. The numbers either side of this range
are told apart the same way: below 3400 a code object has no
co_posonlyargcount, and 3430 or more belongs to Python 3.10.
Files with magic 3400 or 3401, from the first 3.8 alpha, have no
co_posonlyargcount. The explorer reads them correctly.
Variants
- Python 1.5 to 2.0 bytecode – 16-bit numbers in a code object, an 8-byte header
- Python 2.1 and 2.2 bytecode – adds cell and free variables
- Python 2.3 to 2.7 bytecode – the numbers become 32-bit
- Python 3.0 to 3.2 bytecode – adds
co_kwonlyargcount; names are Unicode - Python 3.3 to 3.5 bytecode – a 12-byte header with the source size
- Python 3.6 bytecode – two-byte instructions
- Python 3.7 bytecode – a 16-byte header with flags and hash-based files
- Python 3.8 and 3.9 bytecode – adds
co_posonlyargcount - Python 3.10 bytecode –
co_linetablereplacesco_lnotab; jumps count instructions - Python 3.11 and later bytecode – locals in one list, a location table, an exception table and inline caches
Links
Software
- CPython – the Python interpreter, which writes and loads these files (Windows, macOS, Linux)
- uncompyle6 – decompiler for Python bytecode up to 3.8 (any system with Python)
- decompyle3 – decompiler for Python 3.7 and 3.8 bytecode (any system with Python)
- Decompyle++ (pycdc) – decompiler and disassembler for .pyc files (Windows, macOS, Linux)
Developers
- dis – disassembler for Python bytecode (Python)
- marshal – reads and writes the object format used in the file (Python)
- py_compile – compiles a source file and writes its .pyc file (Python)
- importlib – Python’s import system, including the header checks (Python)
- xdis – disassembler that reads bytecode from many Python versions (Python)
Reference
- Python Bytecode Instructions – the instruction list in the 3.9
disdocumentation - PEP 3147 – the
__pycache__folder and its file names - PEP 552 – the flags field and hash-based .pyc files
- PEP 570 – positional-only parameters, the reason for
co_posonlyargcount