.PYC
Compiled Python bytecode
Introduction
When Python imports a module from a .py
file, it compiles it to bytecode and saves the result as a .pyc file, so
the next import can skip compiling. Python 3 keeps these files in a
__pycache__ folder beside the source, named for the interpreter that made
them, such as module.cpython-312.pyc.
The bytecode changes between Python versions, so a .pyc file only runs on
the version that wrote it. The magic number at the start says which one that is.
Software
- Python, which writes and loads them, and whose
dismodule shows the bytecode (Windows, macOS, Linux) - Decompyle++ (pycdc) (Windows, macOS, Linux)
- uncompyle6, for older Python versions (any system with Python)
Structure
Since Python 3.7 a .pyc file starts with a 16-byte header. The first four
bytes are the magic number: two bytes that change with each bytecode version, then
0D 0A. Next is a 32-bit flags field. When it is 0, the next eight bytes
are the source file’s modification time and size, used to tell whether the cache is
stale. When bit 0 is set, they are instead a hash of the source. The rest of the file is
the module’s code object, written with Python’s marshal module.
Older files have shorter headers: 12 bytes in Python 3.3 to 3.6 (no flags field) and 8 bytes before that (no source size).
0magic, the bytecode version, ending0D 0A4 bytes4flags: 0 for a timestamp check, bit 0 for a hash check4 bytes8source mtime and source size, or a source hash8 bytes16code object, inmarshalformatvaries