Skip to main content

Lib/py_compile.py

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py

py_compile provides a single public function, compile(), that reads a Python source file, compiles it to bytecode, and writes the result as a .pyc file under __pycache__. It is the minimal public surface over the same machinery that importlib uses when it auto-compiles modules on import.

The module defines PycInvalidationMode, an IntEnum with three members: TIMESTAMP (the historical default), CHECKED_HASH, and UNCHECKED_HASH. The mode controls what is written into the .pyc header so that the import system can decide whether cached bytecode is still valid. It also exposes PyCompileError, a thin exception wrapper that formats a friendly message pointing at the offending file and line.

The compile() function is the workhorse. It resolves source and cache paths, reads the source bytes, delegates compilation to importlib.util.source_to_code, then calls into importlib._bootstrap_external to stamp the header and write the .pyc atomically. The quiet parameter suppresses PyCompileError and makes the function return a status integer instead of raising.

Map

LinesSymbolRolegopy
1-30module headerImports, __all__, docstring-
31-60PyCompileErrorException with formatted message and underlying SyntaxError-
61-100PycInvalidationModeIntEnum with TIMESTAMP, CHECKED_HASH, UNCHECKED_HASH-
101-140compile() signature + path setupArgument defaulting, cfile resolution via importlib.util.cache_from_source-
141-180compile() source readOpens source with io.open_code, reads bytes, handles OSError-
181-230compile() compilationCalls importlib.util.source_to_code, catches SyntaxError, wraps in PyCompileError-
231-265compile() writeCalls _bootstrap_external._write_atomic with magic + header + marshalled code-
266-290main() / __main__ blockCLI: iterates sys.argv[1:], calls compile(), prints errors-

Reading

PyCompileError (lines 31 to 60)

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py#L31-60

PyCompileError wraps any exception raised during compilation and produces a human-readable message that includes the filename and, when the underlying error is a SyntaxError, the line number. The exc_value attribute preserves the original exception for programmatic inspection.

class PyCompileError(Exception):
def __init__(self, exc_type, exc_value, file, msg=''):
self.exc_type_name = exc_type.__name__
self.exc_value = exc_value
self.file = file
# builds self.msg from the above, including lineno when available
super().__init__(msg or self.msg)

PycInvalidationMode enum (lines 61 to 100)

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py#L61-100

The three members map directly to the .pyc header flags defined in importlib._bootstrap_external. TIMESTAMP stores the source mtime and size. CHECKED_HASH stores a hash that the import system verifies on every load. UNCHECKED_HASH stores a hash but the import system trusts it without re-checking.

class PycInvalidationMode(enum.IntEnum):
TIMESTAMP = 1
CHECKED_HASH = 2
UNCHECKED_HASH = 3

Path resolution in compile() (lines 101 to 140)

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py#L101-140

When cfile is omitted, the cache path is derived from the source path using importlib.util.cache_from_source, which inserts the __pycache__ subdirectory and appends the magic-number suffix. The dfile parameter (display filename) lets callers embed a different path in tracebacks, for example when compiling from a temporary copy.

if cfile is None:
if optimize >= 0:
cfile = importlib.util.cache_from_source(file, optimization=optimize or '')
else:
cfile = importlib.util.cache_from_source(file)

Compilation and error wrapping (lines 181 to 230)

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py#L181-230

importlib.util.source_to_code is a thin wrapper around the built-in compile(). Any SyntaxError (or subclass) it raises is caught and re-raised as PyCompileError. With quiet >= 2 the error is swallowed entirely and the function returns ''.

try:
code = loader.source_to_code(source_bytes, dfile or file,
_optimize=optimize)
except SyntaxError as err:
py_exc = PyCompileError(err.__class__, err, dfile or file)
if quiet < 2:
raise py_exc
return ''

Writing the .pyc file (lines 231 to 265)

cpython 3.14 @ ab2d84fe1023/Lib/py_compile.py#L231-265

The header is assembled by _bootstrap_external helpers: magic number (4 bytes), flags word, then either mtime+size or hash depending on the invalidation mode. The marshalled code object follows. _write_atomic writes to a temp file and renames, so a concurrent reader never sees a partial .pyc.

bytecode = importlib._bootstrap_external._code_to_timestamp_pyc(
code, source_mtime, source_size)
importlib._bootstrap_external._write_atomic(cfile, bytecode, mode)

gopy mirror

Not yet ported.