What is the PYO file format?
A .pyo file is a legacy Python optimized bytecode file produced by the CPython interpreter when run with the -O (optimize) or -OO flag. Passing -O strips assert statements from the compiled bytecode; passing -OO additionally removes all docstrings, reducing file size slightly.
Internally, .pyo files are byte-for-byte identical in format to .pyc files: a 16-byte header (4-byte version-specific magic number, 4-byte flags field, 4-byte timestamp or source hash, 4-byte source size) followed by a marshalled CPython code object. The optimization level is reflected only in the compiled content - never in the file header.
The .pyo extension was deprecated in Python 3.5 by PEP 488 (September 2015) and is no longer generated by any current Python release. From Python 3.5 onward, optimized bytecode is stored inside __pycache__ with names like module.cpython-311.opt-1.pyc (for -O) or .opt-2.pyc (for -OO). If you encounter a .pyo file today, it originates from Python 2 or Python 3.0-3.4 code.
.pyo files are not portable across CPython versions - the magic number changes with each release. Tools such as uncompyle6 (Python 2-3.8) and decompyle3 (Python 3.7-3.11) can decompile .pyo files back to approximate .py source, though accuracy varies by Python version and code complexity.
Security & safety
RISK: MEDIUMA .pyo file executes as Python bytecode with all the capabilities of a Python script - file system access, network, subprocess execution. Never run a .pyo from an untrusted source. Antivirus software often does not scan .pyo content. Malicious Python apps are sometimes distributed as bytecode-only (.pyc/.pyo) to make reverse engineering harder, though decompilers can largely recover the source.
Format details
in a nutshellPrograms that open PYO files
Technical details
deep spec| Format relationship | Byte-for-byte identical file format to `.pyc`; distinguished only by the filename extension and optimization content |
| Header structure | 16-byte header: 4-byte version magic + 4-byte flags + 4-byte source mtime or hash + 4-byte source size |
| Body format | Marshalled CPython code object (bytecode instructions, constants pool, names, varnames, nested code objects) |
| Byte order | Little-endian (CPython marshal serialization format) |
| Optimization level -O | Strips `assert` statements from compiled bytecode |
| Optimization level -OO | Strips `assert` statements and all docstrings from compiled bytecode |
| Deprecation | `.pyo` extension eliminated in Python 3.5 (PEP 488, September 2015); not generated by any current Python release |
| Modern equivalent | `module.cpython-3X.opt-1.pyc` (level 1) or `.opt-2.pyc` (level 2) stored in `__pycache__` |
| Version portability | Not portable across CPython versions; the magic number in bytes 0-3 changes with each major CPython release |
| Integrity validation | Python 3.7+ (PEP 552): optional SipHash of source stored in header flags; Python 2 / early 3: mtime comparison only |
| Decompilation tools | `uncompyle6` (Python 2-3.8), `decompyle3` (Python 3.7-3.11) |
| Legacy scope | Produced only by Python 2 or Python 3.0-3.4; not encountered in projects targeting Python 3.5 or later |
| Released | Early CPython (1990s); same as .pyc but with optimizations (assert removal with -O; docstring removal with -OO) |
| Latest version | DEPRECATED in Python 3.5 (PEP 488, September 2015) - .pyo extension no longer generated; replaced by .cpython-3X.opt-1.pyc / .opt-2.pyc naming |
| Open standard | Yes · royalty-free |
| Specification | peps.python.org |
PYO conversions
Community Q&A
asked by usersNo questions yet - be the first to ask about PYO files.