How _frozen_importlib Bootstraps Python Imports

Python relies on its own importlib package to find, load, and manage modules, which creates a classic chicken-and-egg dilemma: the interpreter needs an import system to load the Python files that define the import system. To resolve this circular dependency, Python embeds a pre-compiled, bytecode version of its core import machinery directly into the CPython binary under the module name _frozen_importlib. This article explains how _frozen_importlib bridges the gap during interpreter startup, enabling a self-hosting import system to initialize without relying on external filesystem imports.

The Bootstrapping Dilemma

Historically, Python's import machinery was implemented entirely in C. With Python 3.3, the core import logic was rewritten in pure Python via importlib (specifically importlib._bootstrap and importlib._bootstrap_external). While writing the logic in Python makes the import machinery easier to maintain, customize, and test, it creates a fundamental bootstrapping problem. At interpreter startup, basic capabilities such as parsing file paths, reading files from disk, and compiling Python source code to bytecode depend on the very import machinery that has not yet been loaded.

What Is a Frozen Module?

A frozen module in CPython is a Python module whose compiled bytecode is embedded directly inside the CPython executable or shared library as a static C array of bytes. Because the bytecode is compiled at build time, the interpreter can load and execute it without:

During the CPython build process, a helper tool compiles Lib/importlib/_bootstrap.py into bytecode and transforms those bytes into a C header file. When CPython is compiled, this bytecode becomes baked directly into the C runtime.

The Startup and Bootstrapping Sequence

CPython uses _frozen_importlib to bootstrap the runtime through a carefully ordered sequence:

  1. Primitive C Initialization: The interpreter starts by initializing fundamental C-level structures, memory allocators, and built-in modules like sys and builtins.
  2. Loading _frozen_importlib: The runtime invokes a minimal C-level loader capable exclusively of executing frozen bytecode arrays stored in memory. It executes the frozen bytecode of importlib._bootstrap, exposing it as the module _frozen_importlib.
  3. Setting Up Core Importers: Once executed, _frozen_importlib establishes foundational classes (such as ModuleSpec) and registers primitive finders onto sys.meta_path. These initial finders only know how to load built-in modules (BuiltinImporter) and other frozen modules (FrozenImporter).
  4. Loading External Import Machinery: With primitive importing operational, the runtime loads _frozen_importlib_external (the frozen version of importlib._bootstrap_external). This module provides file-system-aware classes, including FileFinder, SourceFileLoader, and PathFinder.
  5. Enabling Filesystem Imports: The external importers are appended to sys.meta_path, allowing Python to locate .py and .pyc files on disk, inspect sys.path, and resolve standard packages.

Finalizing the Import System

After _frozen_importlib and _frozen_importlib_external are initialized, the bootstrapping phase ends. The runtime can now import standard library modules directly from disk.

When user code later runs import importlib, the standard library module simply re-exports the components already defined in memory by _frozen_importlib. This architecture allows Python to maintain an import subsystem written almost entirely in high-level Python code while avoiding runtime circular dependencies during startup.