Skip to main content

Python/frozen.c

Source:

cpython 3.14 @ ab2d84fe1023/Python/frozen.c

Python/frozen.c provides the _PyImport_FrozenModules table that maps module names to pre-compiled bytecode. These modules are embedded directly in the interpreter binary and importable before sys.path is set up.

Map

LinesSymbolRole
1-20Includes<Python.h>, frozen.h (generated by Makefile)
21-80_PyImport_FrozenModulesTable of {name, code, size} entries
81-120_PyImport_FrozenAliasesName aliases (e.g., _frozen_importlibimportlib._bootstrap)

Reading

Frozen module table

// CPython: Python/frozen.c:30 _PyImport_FrozenModules
const struct _frozen _PyImport_FrozenModules[] = {
/* Modules needed before the filesystem importer is available */
{"_frozen_importlib", _Py_M__importlib__bootstrap,
(int)sizeof(_Py_M__importlib__bootstrap)},
{"_frozen_importlib_external", _Py_M__importlib__bootstrap_external,
(int)sizeof(_Py_M__importlib__bootstrap_external)},
{"zipimport", _Py_M__zipimport,
(int)sizeof(_Py_M__zipimport)},
/* stdlib modules frozen for startup speed in 3.11+ */
{"abc", _Py_M__abc, (int)sizeof(_Py_M__abc)},
{"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs)},
...
{0, 0, 0} /* sentinel */
};

The bytecode arrays (_Py_M__*) are generated by Tools/build/freeze_modules.py and emitted into Python/frozen_modules/.

Alias table

// CPython: Python/frozen.c:90 _PyImport_FrozenAliases
const struct _module_alias _PyImport_FrozenAliases[] = {
{"_frozen_importlib", "importlib._bootstrap"},
{"_frozen_importlib_external", "importlib._bootstrap_external"},
{0, 0}
};

Aliases allow import importlib._bootstrap to resolve to the same bytecode as import _frozen_importlib.

Lookup at import time

// CPython: Python/import.c:1480 find_frozen
static const struct _frozen *
find_frozen(PyObject *name, struct _frozen_module_info *info)
{
const struct _frozen *p = PyImport_FrozenModules;
for (; p->name != NULL; p++) {
if (strcmp(p->name, PyUnicode_AsUTF8(name)) == 0) {
/* Found: return pointer to bytecode blob */
info->data = p->code;
info->size = p->size < 0 ? -(p->size) : p->size;
info->is_package = p->size < 0;
return p;
}
}
return NULL;
}

A negative size field marks the module as a package (has a __path__).

gopy notes

In gopy the frozen module table is in stdlibinit/registry.go. Python bytecode blobs are not used; instead, the stdlib modules are compiled from source (.py files vendored in stdlib/) at build time and registered in the table as pre-parsed ASTs or as source strings. The bootstrap modules (_frozen_importlib, _frozen_importlib_external) are handled specially: gopy's own import machinery replaces them so no bytecode embedding is needed.