Introduction
When CPython imports a module from a
.py file, it compiles the source to bytecode
and saves the result as a .pyc file in a __pycache__ folder
beside the source. The next import loads the .pyc file and skips the
compiler. The file holds the module’s code object: its instructions, constants and
names, with the code object of every function and class nested inside.
This page covers the format written by Python 3.11 and every release since, up to 3.15. Python 3.11 rebuilt the code object: local, cell and free variables share one list, a qualified name was added, line numbers became a table that also records columns, and exception handling moved from instructions into a table of its own. Instructions gained inline caches.
The file layout has not changed since 3.11, but every release numbers its instructions differently, so the magic number at the start of the file decides which instruction each byte means. A file only runs on the release that wrote it.
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
A file is a 16-byte header followed by one object in Python’s
marshal format, the module’s code object. All numbers are little-endian.
0magic: a release’s number, then0D 0A4 bytes4flags: 0 for a date check, 1 or 3 for a hash check4 bytes8source_mtime and source_size, or source_hash8 bytes16code object of the module, onemarshalobjectvaries
The code object holds counts, flags, the instructions as a byte string, a tuple of constants (which holds nested code objects), and tables of names, source positions and exception handlers.
What each release changed
The header and the shape of the code object are the same in every release below. What changes is the instruction set, and with it the numbering, argument rules and inline cache sizes. Each release has its own column in the instruction table.
| Release | Final magic | Changes |
|---|---|---|
| 3.11 | 3495 | The format as this variant has it: the combined locals list, co_qualname, the location table, the exception table and inline caches. Calls use PRECALL and CALL; jumps come in forward and backward forms. |
| 3.12 | 3531 | PRECALL and LOAD_METHOD are gone; the low bit of LOAD_ATTR’s argument asks for a method. COMPARE_OP holds its operator above bit 4. Conditional jumps only go forward. Comprehensions are inlined, which adds the hidden flag on locals. CALL_INTRINSIC_1 and _2, LOAD_SUPER_ATTR and RETURN_CONST are added. |
| 3.13 | 3571 | Instructions are renumbered, in alphabetical blocks. TO_BOOL, CALL_KW, SET_FUNCTION_ATTRIBUTE, FORMAT_SIMPLE and FORMAT_WITH_SPEC are added; KW_NAMES and FORMAT_VALUE are gone. COMPARE_OP’s operator moves above bit 5. Jumps carry an inline cache. |
| 3.14 | 3627 | marshal version 5, with slice constants. BINARY_SUBSCR becomes BINARY_OP; LOAD_SMALL_INT, LOAD_COMMON_CONSTANT, LOAD_SPECIAL, LOAD_FAST_BORROW, NOT_TAKEN, POP_ITER and the template-string instructions are added. RETURN_CONST and BEFORE_WITH are gone. RESUME moves to 128. co_flags gains HAS_DOCSTRING and METHOD. |
| 3.15 | 3666 | marshal version 6. RESUME and GET_ITER have inline caches; GET_ITER takes an argument and replaces GET_YIELD_FROM_ITER. IMPORT_NAME’s argument holds lazy-import bits below the name index. TRACE_RECORD is added. |
Every magic number of every pre-release is on the header page. Numbers 3450 to 3459 and the alpha releases before 3494 still had earlier forms of the code object and line table. No final release wrote them.
Telling it apart
The first two bytes, little-endian, are the magic number; they are 3450 or more, and
below 4000. The next two bytes are 0D 0A. The explorer takes these numbers
and then reads the file strictly: only 0, 1 and 3 are valid flags, and the code object
must fill the rest of the file exactly.
Files of Python 3.10 have a smaller magic number, a code object with
co_nlocals, co_varnames, co_freevars and
co_cellvars, and no exception table.
00000000 2B 0E 0D 0A 00 00 00 00 00 F1 53 65 06 00 00 00
Variants
- Python 1.5 to 2.0 bytecode – 8-byte header, one or three-byte instructions and 16-bit numbers in the code object
- Python 2.1 and 2.2 bytecode – adds free and cell variables to the code object
- Python 2.3 to 2.7 bytecode – the code object’s numbers become 32-bit
- Python 3.0 to 3.2 bytecode – keyword-only arguments; text and bytes become separate types
- Python 3.3 to 3.5 bytecode – 12-byte header with the source size; object references from 3.4
- Python 3.6 bytecode – two-byte instructions
- Python 3.7 bytecode – 16-byte header with a flags field
- Python 3.8 and 3.9 bytecode – positional-only arguments
- Python 3.10 bytecode –
co_linetable, and jumps that count instructions - Python 3.11 and later bytecode – one list of locals, a location table, an exception table and inline caches
Links
Software
- CPython – the Python interpreter, which writes and loads these files;
python -m disshows the bytecode (Windows, macOS, Linux) - Decompyle++ (pycdc) – disassembler and decompiler for
.pycfiles of many Python versions (Windows, macOS, Linux)
Developers
- dis – Python’s own bytecode disassembler (Python)
- marshal – Python’s own module for the object format of the body (Python)
- py_compile – Python’s own module that writes
.pycfiles (Python) - importlib – Python’s import system, which reads and checks them (Python)
- xdis – cross-version disassembler (Python)
Reference
- dis – Python’s documentation of its bytecode instructions (Python 3.15)
- marshal – Python’s documentation of the module and its version numbers
- importlib – Python’s documentation of the import system
- PEP 3147 – the
__pycache__folder and its file names - PEP 552 – the flags field and hash-based
.pycfiles - PEP 626 – precise line numbers for tracing
- PEP 657 – columns in the location table
- locations.md – CPython’s description of the location table (Python 3.11)
- exception_handling.md – CPython’s description of the exception table (Python 3.14)
- pycore_magic_number.h – CPython’s list of magic numbers (Python 3.15)