Python/frozen.c (part 2)
Source:
cpython 3.14 @ ab2d84fe1023/Python/frozen.c
This annotation covers the extended set of frozen modules added in Python 3.11-3.14. See python_frozen_detail for _PyImport_IsFrozenModule, _Py_FrozenBootstrap, and how frozen code is embedded.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1-50 | Frozen aliases | importlib._bootstrap_external alias resolution |
| 51-100 | _PyImport_FrozenAliases | Table mapping alias names to canonical names |
| 101-200 | Standard frozen set | _collections_abc, _abc, posixpath, ntpath, genericpath |
| 201-250 | _Py_FrozenStdlib | Full stdlib frozen set (3.11+ when --enable-frozen-modules) |
Reading
Why these modules are frozen
// CPython: Python/frozen.c:12 comment
/* These modules are frozen into the interpreter to allow the import system
to start without needing a working file system. They must be loadable
before the path-based finder is available.
Bootstrap order:
1. _frozen_importlib (importlib._bootstrap)
2. _frozen_importlib_external (importlib._bootstrap_external)
3. zipimport
4. _collections_abc, _abc (needed by importlib internals)
5. posixpath / ntpath (needed for path manipulation in bootstrap)
*/
_PyImport_FrozenAliases
// CPython: Python/frozen.c:55 _PyImport_FrozenAliases
static const struct _frozen _PyImport_FrozenAliases[] = {
/* Bootstrap aliases */
{"_frozen_importlib", NULL, 0, 0, "_bootstrap"},
{"_frozen_importlib_external", NULL, 0, 0, "_bootstrap_external"},
/* Stdlib aliases (3.11+) */
{"importlib._bootstrap", M__importlib__bootstrap,
sizeof(M__importlib__bootstrap), 0},
{"importlib._bootstrap_external", M__importlib__bootstrap_external,
sizeof(M__importlib__bootstrap_external), 0},
{0, 0, 0, 0} /* sentinel */
};
Alias entries have a NULL code pointer. The import machinery resolves them to the canonical name and finds the actual frozen data there.
Standard frozen modules (3.11+)
// CPython: Python/frozen.c:130 _PyImport_FrozenStdlib
/* When --enable-frozen-modules is used at build time, additional stdlib
modules are compiled into frozen bytecode. This speeds up startup
by avoiding disk reads for commonly-imported modules. */
static const struct _frozen _PyImport_FrozenStdlib[] = {
/* abc, codecs, collections, functools, io, os, ... */
{"abc", M_abc, sizeof(M_abc), 0},
{"codecs", M_codecs, sizeof(M_codecs), 0},
{"os", M_os, sizeof(M_os), 0},
...
{0, 0, 0, 0}
};
How frozen bytecode is generated
# CPython Makefile:
# Python/frozen_modules/*.h are generated by:
# python Tools/freeze/freeze.py Lib/importlib/_bootstrap.py
# python Tools/build/freeze_modules.py
# Each .h file contains:
# static unsigned char M_importlib__bootstrap[] = { ... bytecode bytes ... };
The bytecode is stored as a C array literal. At startup, _PyImport_FindFrozenObject finds the entry by name and returns a PyBytesObject wrapping the array (no copy needed).
gopy notes
gopy embeds the same frozen modules at build time using Go's //go:embed directive in stdlibinit/frozen.go. The bytecode arrays are in stdlib/frozen/ as Go []byte variables. _PyImport_IsFrozenModule is vm.IsFrozenModule in vm/eval_import.go. Frozen aliases are resolved in the same function.