imp

package
v0.12.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

init_importlib sequence. Mirrors the two-phase importlib bootstrap in pylifecycle.c: first the pure-Python _frozen_importlib is installed, then _frozen_importlib_external extends it.

In gopy the frozen code objects start as nil placeholders (see frozen_bootstrap.go). InitImportlib returns ErrBootstrapNotReady when the code objects have not been embedded yet; callers in the early lifecycle can treat this as a soft error and proceed with a reduced import system.

CPython: Python/pylifecycle.c:L987 init_importlib CPython: Python/pylifecycle.c:L1041 init_importlib_external

ExecCodeModule: execute a code object in a module's namespace and register the result in sys.modules. Mirrors PyImport_ExecCodeModule.

CPython: Python/import.c:L644 PyImport_ExecCodeModule CPython: Python/import.c:L670 exec_code_in_module

Package imp is the Go port of CPython's import machinery. imp/frozen.go implements the frozen module table: code objects that are compiled into the interpreter and can be imported without touching the filesystem.

CPython: Python/frozen.c CPython: Python/import.c:L1240 import_find_frozen CPython: Include/import.h:L24 struct _frozen

Frozen bootstrap module registrations. These correspond to the modules that CPython compiles from Lib/importlib/_bootstrap.py and Lib/importlib/_bootstrap_external.py at build time and embeds as frozen bytecode.

In gopy the Code fields start as nil (placeholder). They are filled in by the imp/bootstrap.go init sequence once the compiler produces compatible code objects.

CPython: Python/frozen.c:L56 _PyImport_FrozenModules bootstrap entries

ImportModuleLevel: the primary entry point for the import statement. Mirrors PyImport_ImportModuleLevelObject: check sys.modules, then try frozen modules, then built-in (inittab) modules. File-based loading via sys.path finders is deferred to the importlib bootstrap.

CPython: Python/import.c:L1561 PyImport_ImportModuleLevelObject CPython: Python/import.c:L1450 PyImport_ImportModule

Built-in module initializer table. Mirrors _PyImport_Inittab: a list of (name, initfunc) pairs for modules that are compiled in. AppendInittab registers new entries; FindInitFunc looks them up.

CPython: Python/import.c:L173 _PyImport_Inittab CPython: Python/import.c:L243 PyImport_AppendInittab CPython: Python/import.c:L212 PyImport_ExtendInittab

Source and bytecode loaders. Mirrors the CPython SourceFileLoader and SourcelessFileLoader from Lib/importlib/_bootstrap_external.py.

LoadPyc reads a .pyc file and calls ExecCodeModule. LoadSource compiles a .py file via a caller-provided SourceCompiler then calls ExecCodeModule; the compiler function is injected to avoid a circular import between imp and the parser/compile packages.

CPython: Lib/importlib/_bootstrap_external.py:L1045 SourceFileLoader CPython: Lib/importlib/_bootstrap_external.py:L1215 SourcelessFileLoader

Path-based finder. Mirrors the trio of CPython classes that locate a module on disk:

PathFinder         - meta-path entry that walks sys.path
FileFinder         - per-directory finder
SourceFileLoader   - loads + compiles .py files

The CPython chain sits inside _frozen_importlib_external; the classes are full Python objects with caches, namespace-package support, and a path_importer_cache hook. gopy ports the slice that import statements actually exercise: walk a list of directories, look for `<tail>.py` or `<tail>/__init__.py`, hand the file to the existing LoadSourceFile path. Caching, .pyc fallback, namespace packages, and the path_hooks plumbing land later.

CPython: Lib/importlib/_bootstrap_external.py:1196 PathFinder CPython: Lib/importlib/_bootstrap_external.py:1322 FileFinder CPython: Lib/importlib/_bootstrap_external.py:962 SourceFileLoader

ReloadModule: re-execute a module against its existing namespace so importlib.reload(m) keeps the same module object alive while picking up new definitions. Mirrors PyImport_ReloadModule, which delegates to importlib.reload; gopy has no working importlib bootstrap yet, so we inline the bits of the Python-level reload that matter for the frozen and built-in module cases.

CPython: Python/import.c:3983 PyImport_ReloadModule CPython: Lib/importlib/__init__.py:94 reload

sys.modules registry. Mirrors the interp->modules dict that CPython uses as the global module cache. The dict returned by SysModules is the same object Python code sees as sys.modules: every import path writes through it, every cache hit reads from it.

CPython: Python/import.c:L276 PyImport_GetModule CPython: Python/import.c:L297 PyImport_AddModule CPython: Python/import.c:L329 PyImport_RemoveModule

Index

Constants

This section is empty.

Variables

View Source
var ErrBootstrapNotReady = errors.New("imp: bootstrap: frozen importlib code objects are not yet embedded")

ErrBootstrapNotReady is returned when the frozen importlib code objects have not been embedded yet (placeholder state).

View Source
var ErrModuleNotFound = fmt.Errorf("imp: ModuleNotFoundError")

ErrModuleNotFound is returned when no finder can locate the named module.

Functions

func AddModule

func AddModule(name string, mod *objects.Module) *objects.Module

AddModule adds mod to sys.modules under name. If an entry already exists it is replaced. The module pointer is returned for chaining.

CPython: Python/import.c:L297 PyImport_AddModule

func AppendInittab

func AppendInittab(name string, init InitFunc) error

AppendInittab adds a single built-in module entry. It is safe to call from multiple goroutines and from init().

CPython: Python/import.c:L243 PyImport_AppendInittab

func ExecCodeModule

func ExecCodeModule(exec Executor, name string, code *objects.Code) (*objects.Module, error)

ExecCodeModule executes code in a fresh module named name, sets the standard dunder attributes, registers the module in sys.modules, and returns it. If name is already in sys.modules the existing module is reused so that partially-initialized modules see updates in-place.

CPython: Python/import.c:L644 PyImport_ExecCodeModule

func ExtendInittab

func ExtendInittab(entries []InittabEntry) error

ExtendInittab appends multiple entries at once. It stops and returns an error if any entry has a nil Init.

CPython: Python/import.c:L212 PyImport_ExtendInittab

func GetModule

func GetModule(name string) (*objects.Module, bool)

GetModule returns the module registered under name in sys.modules, or (nil, false) if absent or if the entry is not a module.

CPython: Python/import.c:L276 PyImport_GetModule

func ImportModule

func ImportModule(exec Executor, name string) (*objects.Module, error)

ImportModule performs an absolute import of name. It is the zero-level convenience wrapper around ImportModuleLevel.

CPython: Python/import.c:L1450 PyImport_ImportModule

func ImportModuleLevel

func ImportModuleLevel(exec Executor, name, pkgname string, level int) (*objects.Module, error)

ImportModuleLevel imports name relative to pkgname at the given level. level=0 is an absolute import; level>0 is relative.

The lookup order is:

  1. sys.modules cache
  2. Frozen modules (FrozenModule table)
  3. Built-in modules (Inittab)
  4. ErrModuleNotFound

File-based imports via sys.path and the importlib finder chain are resolved by the importlib bootstrap (imp/bootstrap.go), which registers a custom __import__ hook after it initializes.

CPython: Python/import.c:L1561 PyImport_ImportModuleLevelObject

func InitImportlib

func InitImportlib(exec Executor, sysmod *objects.Module) error

InitImportlib runs phase 1 of the importlib bootstrap: executes the _frozen_importlib code object and installs the resulting module into sys.modules. It then calls the module's _install(sys_module) hook.

Returns ErrBootstrapNotReady when the frozen code object has not been embedded yet.

CPython: Python/pylifecycle.c:L987 init_importlib

func InitImportlibExternal

func InitImportlibExternal(exec Executor) error

InitImportlibExternal runs phase 2 of the importlib bootstrap: executes _frozen_importlib_external and calls its _install hook with the _frozen_importlib module.

CPython: Python/pylifecycle.c:L1041 init_importlib_external

func IsFrozen

func IsFrozen(name string) bool

IsFrozen reports whether name is in the frozen module table, regardless of whether its Code field is populated.

CPython: Python/import.c:L1268 PyImport_IsFrozenModule

func LoadPyc

func LoadPyc(exec Executor, filename, name string) (*objects.Module, error)

LoadPyc opens filename, validates the .pyc header, and executes the embedded code object in a module named name. The returned module is registered in sys.modules.

CPython: Lib/importlib/_bootstrap_external.py:L1215 SourcelessFileLoader.exec_module

func LoadSource

func LoadSource(exec Executor, compiler SourceCompiler, src, filename, name string) (*objects.Module, error)

LoadSource compiles src to a code object via compiler, then executes it in a module named name. The returned module is registered in sys.modules.

CPython: Lib/importlib/_bootstrap_external.py:L1045 SourceFileLoader.exec_module

func LoadSourceFile

func LoadSourceFile(exec Executor, compiler SourceCompiler, filename, name string) (*objects.Module, error)

LoadSourceFile reads filename, compiles it via compiler, and calls LoadSource. It is a convenience wrapper for the common case of loading from disk.

CPython: Lib/importlib/_bootstrap_external.py:L1045 SourceFileLoader.get_code

func RegisterFrozen

func RegisterFrozen(m *FrozenModule)

RegisterFrozen adds or replaces a frozen module in the table. It is safe to call from multiple goroutines and from init().

CPython: Python/frozen.c — populated at link time via _PyImport_FrozenModules

func ReloadModule added in v0.10.1

func ReloadModule(exec Executor, mod *objects.Module) (*objects.Module, error)

ReloadModule re-executes mod's underlying source against its existing __dict__. The module pointer is preserved so callers that already hold a reference observe the new bindings in place.

The lookup mirrors ImportModuleLevel's order without the sys.modules short-circuit: frozen modules first, then the inittab. Source-only modules cannot be reloaded yet because gopy does not retain the originating Code on the module.

CPython: Python/import.c:3983 PyImport_ReloadModule CPython: Lib/importlib/__init__.py:94 reload

func RemoveModule

func RemoveModule(name string)

RemoveModule removes the module registered under name. It is a no-op if name is not present.

CPython: Python/import.c:L329 PyImport_RemoveModule

func SetPathFinder added in v0.12.3

func SetPathFinder(f *PathFinder)

SetPathFinder installs the package-level PathFinder consulted by ImportModuleLevel after the inittab miss. Callers (lifecycle, cmd/gopy, tests) build a PathFinder with the desired Paths and Compiler and pass it here once at startup.

Passing nil clears the finder, which is useful for tests that want to confirm an import fails when path-based lookup is disabled.

func SysModules added in v0.12.3

func SysModules() *objects.Dict

SysModules returns the dict backing sys.modules. The same pointer is stamped onto the sys module as `sys.modules` so Python and Go share one view of the cache.

CPython: Python/sysmodule.c interp->modules

func SysModulesSnapshot

func SysModulesSnapshot() map[string]*objects.Module

SysModulesSnapshot returns a shallow copy of sys.modules as a plain Go map. Callers receive a stable snapshot; later mutations to the registry are not reflected. Non-module entries are skipped.

CPython: Python/sysmodule.c interp->modules

Types

type Executor

type Executor interface {
	ExecCode(code *objects.Code, mod *objects.Module) (objects.Object, error)
}

Executor is the minimal interface the bootstrap needs from the eval loop: execute a code object in the given module's namespace and return its result.

CPython: Python/ceval.c:L753 _PyEval_EvalCode (simplified)

type FrozenModule

type FrozenModule struct {
	// Name is the dotted module name, e.g. "importlib._bootstrap".
	Name string
	// Code is the precompiled code object. nil for placeholder entries.
	Code *objects.Code
	// IsPackage is true when the frozen module is a package (has __path__).
	IsPackage bool
}

FrozenModule holds a single frozen module entry. A nil Code pointer means the module is a known-frozen name but the bytecode has not yet been embedded (placeholder state).

CPython: Include/import.h:L24 struct _frozen

func FindFrozen

func FindFrozen(name string) (*FrozenModule, bool)

FindFrozen looks up a frozen module by exact dotted name. It returns the entry and true if found, nil and false otherwise.

CPython: Python/import.c:L1240 import_find_frozen

func FrozenList

func FrozenList() []*FrozenModule

FrozenList returns a snapshot of all registered frozen modules.

type InitFunc

type InitFunc func() (*objects.Module, error)

InitFunc is the initializer signature for a built-in module. It mirrors the C Py_InitProc signature.

CPython: Include/import.h:L8 PyImport_InitModuleFunc

func FindInitFunc

func FindInitFunc(name string) InitFunc

FindInitFunc returns the InitFunc registered for name, or nil if the module is not in the built-in table.

CPython: Python/import.c:L256 _PyImport_FindExtensionObjectUnicode

type InittabEntry

type InittabEntry struct {
	Name string
	Init InitFunc
}

InittabEntry is one row in the built-in module table.

CPython: Include/import.h:L12 struct _inittab

func InittabSnapshot

func InittabSnapshot() []InittabEntry

InittabSnapshot returns a copy of the current built-in module table.

type PathFinder added in v0.12.3

type PathFinder struct {
	// Paths is the ordered directory list. Entries are absolute or
	// relative to the process cwd; empty entries are treated as ".".
	// CPython: Lib/importlib/_bootstrap_external.py:1290 path = sys.path
	Paths []string

	// Compiler is the SourceCompiler used to turn .py source into a
	// code object. It is injected by the runtime to dodge a parser
	// cycle on imp; see loader.go for the same hook on LoadSource.
	// CPython: Python/pythonrun.c:1102 Py_CompileStringExFlags
	Compiler SourceCompiler
}

PathFinder is the gopy port of importlib's PathFinder meta-path hook. It carries the directory list to search (the equivalent of sys.path) plus the SourceCompiler the resulting loader should use.

CPython: Lib/importlib/_bootstrap_external.py:1196 PathFinder

func GetPathFinder added in v0.12.3

func GetPathFinder() *PathFinder

GetPathFinder returns the currently installed PathFinder, or nil.

func (*PathFinder) FindModule added in v0.12.3

func (p *PathFinder) FindModule(exec Executor, name string) (*objects.Module, error)

FindModule walks the directories that should be searched for name and either loads the matching source file as a module, returns errFinderMiss when no entry matched, or returns the loader's error when the file was found but compile/exec failed. Top-level names are searched against Paths; dotted names are searched against the parent package's __path__, matching CPython's FileFinder behavior.

CPython: Lib/importlib/_bootstrap_external.py:1357 FileFinder.find_spec CPython: Lib/importlib/_bootstrap.py:1184 _find_and_load

type SourceCompiler

type SourceCompiler func(src, filename string) (*objects.Code, error)

SourceCompiler compiles Python source text to a code object. Callers (lifecycle, pythonrun) inject a concrete implementation; this breaks the circular dependency between imp and parser/compile.

CPython: Python/pythonrun.c:L1102 Py_CompileStringExFlags

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL