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.10. Line numbers are stored in
co_linetable, a table of byte ranges and line steps, as PEP 626 specifies,
and a jump’s argument counts instructions rather than bytes.
A file only runs on the release that wrote it. The magic number at the start says which one that is.
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: 3439, 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), the names it uses, and a line table. Exception handling is done by instructions in the code, not by a table.
What Python 3.10 changed
- Line numbers moved from
co_lnotabtoco_linetable, which can say that an instruction has no line at all (PEP 626, magic 3431). - A jump’s argument counts instructions instead of bytes (magic 3435).
matchstatements addedMATCH_CLASS,MATCH_KEYS,MATCH_MAPPING,MATCH_SEQUENCE,GET_LENandCOPY_DICT_WITHOUT_KEYS(PEP 634, magic 3434).GEN_STARTandROT_Nwere added.- The annotations passed to
MAKE_FUNCTIONbecame a tuple, not a dictionary. RERAISErestoresf_lastiwhen its argument is nonzero.
Each pre-release number is on the header page. Files of 3430 to 3434 are pre-releases only and differ in the points above.
Telling it apart
The first two bytes, little-endian, are the magic number, and the next two are
0D 0A. The final number of Python 3.10 is 3439, and its pre-releases used
3430 to 3438. The explorer takes this range and reads the file strictly: only 0, 1 and 3
are valid flags, and the code object must fill the rest of the file exactly.
Python 3.11 files have a magic number of 3450 or more, and a code object with no
co_nlocals and with an exception table.
00000000 6F 0D 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.10)
- 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
- lnotab_notes.txt – CPython’s description of the line number table (Python 3.10)