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.14. Its code object keeps local, cell
and free variables in one list, with a qualified name, a location table that records
lines and columns, and an exception table. Some instructions are followed by inline
caches. Python 3.14 writes marshal version 5, which can store slices, and
marks docstrings and methods in the code object’s flags.
The magic number at the start of the file says which release wrote it, and a file only runs on a release with exactly the same number. The final Python 3.14 releases write 3627.
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: 3627, 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 Python 3.14 changed
The header and the order of the code object’s fields are those of Python 3.11 to 3.13. The changes are in the objects and the instructions:
marshalversion 5 adds a slice type, so a constant slice such as the one inx[1:2]can be stored.co_flagsgainsHAS_DOCSTRING, set when the first constant is the docstring, andMETHOD, set on functions defined in a class body.co_localspluskindsmarks arguments: positional, keyword, and*argsor**kwargs.BINARY_SUBSCRbecomesBINARY_OPwith operator 26, andBINARY_OP’s cache grows to 5 units.CALL_KWgains a cache.- New instructions:
LOAD_SMALL_INTholds an integer from 0 to 255 in its argument;LOAD_COMMON_CONSTANTloads a few built-in objects and replacesLOAD_ASSERTION_ERROR;LOAD_SPECIALreplacesBEFORE_WITHandBEFORE_ASYNC_WITH;LOAD_FAST_BORROWandLOAD_FAST_BORROW_LOAD_FAST_BORROW;NOT_TAKENandPOP_ITER; andBUILD_TEMPLATEandBUILD_INTERPOLATIONfor template strings (PEP 750). - Gone:
RETURN_CONST,BUILD_CONST_KEY_MAP,BEFORE_WITH,BEFORE_ASYNC_WITH,BINARY_SUBSCRandLOAD_ASSERTION_ERROR. CALL_FUNCTION_EXno longer takes an argument;END_ASYNC_FORtakes one.RESUMEmoves to 128 andENTER_EXECUTORto 255, and most other instructions are renumbered.SET_FUNCTION_ATTRIBUTEcan set a function’s annotate function, flag0x10.
Every magic number of the 3.14 pre-releases is on the header page. No final release wrote those before 3627.
Telling it apart
The first two bytes, little-endian, are the magic number: 3600 to 3627, and 3627 in
every final 3.14 release. 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.13 have the same layout but a magic number from 3550 to 3571, and number their instructions differently. Files of Python 3.15 have a magic number of 3650 or more.
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 bytecode – one list of locals, a location table, an exception table and inline caches
- Python 3.12 bytecode – inlined comprehensions, method loads folded into
LOAD_ATTR, forward-only conditional jumps - Python 3.13 bytecode – instructions renumbered, explicit conversion to
bool, caches on jumps - Python 3.14 bytecode –
marshalversion 5 with slice constants, small integers in the argument - Python 3.15 bytecode –
marshalversion 6, lazy imports and a cache onRESUME
Links
Software
- CPython – the Python interpreter, which writes and loads these files;
python -m disshows the bytecode (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.14)
- marshal – Python’s documentation of the module and its version numbers (Python 3.14)
- importlib – Python’s documentation of the import system (Python 3.14)
- 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
- code_objects.md – CPython’s description of the code object and the location table (Python 3.14)
- 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.14)