Module loading and import utilities.

This module provides tools for dynamic module loading, fresh imports that bypass sys.modules, monkey patching, and context managers for isolating import side-effects.

Note

Parts of this module are derived from the Python test.support.import_helper module (Copyright (C) 2006 Python Software Foundation, licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2). That module is part of CPython’s test suite and is not guaranteed to be available in all Python distributions or to remain stable between releases (actually it is already absent from some standalone Python build). Those vendored portions have been adapted to fit standard-deluxe public API: CleanImport, DirsOnSysPath, forget_module(), frozen_modules(), import_fresh_module().

Module Contents

Classes

CleanImport

Context manager to force import to return a…

DirsOnSysPath

Context manager to temporarily add directories…

Module

Utility class for dynamic loading of a Python…

monkey

Decorator-based monkey patcher for module…

Functions

loads_module(name, where)

Load a Python module or package from a…

forget_module(name)

Forget a module was ever imported.

import_fresh_module(name, fresh, blocked, *None, deprecated, usefrozen)

Import and return a module, deliberately…

frozen_modules(enabled)

Force frozen modules to be used (or not).

Attributes

Patchable

Type alias for objects that can be the target…

Patch

Type alias for monkey patch callables.

Patchable

Type alias for objects that can be the target of a monkey patch.

Patch

Type alias for monkey patch callables.

loads_module(name: str, where: pathlib.Path) types.ModuleType | None[source]

Load a Python module or package from a filesystem path.

This is a convenience wrapper around Module that resolves and loads the module in a single call.

Parameters:
name: str

The fully qualified module name to load.

where: pathlib.Path

The directory to search for the module in.

Returns:

ModuleType | None – The loaded module if found and successfully imported, None otherwise.

Raises:
forget_module(name: str) None[source]

Forget a module was ever imported.

This removes the module from sys.modules and deletes any PEP 3147/488 or legacy .pyc cached bytecode files found along sys.path.

Parameters:
name: str

The fully qualified module name to forget.

import_fresh_module(
name: str,
fresh: collections.abc.Iterable[str] = (),
blocked: collections.abc.Iterable[str] = (),
*,
deprecated: bool = False,
usefrozen: bool = False,
) types.ModuleType | None[source]

Import and return a module, deliberately bypassing sys.modules.

This function imports and returns a fresh copy of the named Python module by removing the named module from sys.modules before doing the import. Note that unlike importlib.reload(), the original module is not affected by this operation.

The named module and any modules named in the fresh and blocked parameters are saved before starting the import and then reinserted into sys.modules when the fresh import is complete.

Parameters:
name: str

The fully qualified module name to import.

fresh: collections.abc.Iterable[str] = ()

Additional module names that are also removed from the sys.modules cache before the import. If one of these modules cannot be imported, None is returned. Default: ().

blocked: collections.abc.Iterable[str] = ()

Module names that are replaced with None in the module cache during the import to ensure that attempts to import them raise ImportError. Default: ().

deprecated: bool = False

If True, module and package deprecation messages are suppressed during this import. Default: False.

usefrozen: bool = False

If False (the default), the frozen importer is disabled (except for essential modules like importlib._bootstrap). Default: False.

Returns:

ModuleType | None – The freshly imported module, or None if one of the fresh modules could not be imported.

Raises:

ImportError – If the named module cannot be imported.

frozen_modules(enabled: bool = True)[source]

Force frozen modules to be used (or not).

This context manager controls whether the Python importer uses precompiled frozen modules. When disabled, the standard source-based import machinery is used instead.

This only applies to modules that haven’t been imported yet. Some essential modules (e.g. importlib._bootstrap) will always be imported frozen regardless of this setting.

Parameters:
enabled: bool = True

If True, frozen modules are enabled. If False, frozen modules are disabled. Default: True.

Yields:

None – This context manager yields nothing.

class CleanImport(*module_names: str, usefrozen: bool = False)[source]

Context manager to force import to return a new module reference.

This is useful for testing module-level behaviors, such as the emission of a DeprecationWarning on import.

When entered, the named modules are removed from sys.modules so that subsequent imports return fresh references. On exit, the original sys.modules state is restored.

Parameters:
*module_names: str

One or more fully qualified module names to remove from sys.modules.

usefrozen: bool = False

If False (the default), the frozen importer is disabled (except for essential modules like importlib._bootstrap). Default: False.

Examples:

with CleanImport("foo"):
    importlib.import_module("foo")  # fresh import
original_modules : dict[str, types.ModuleType]
class DirsOnSysPath(*paths: str)[source]

Context manager to temporarily add directories to sys.path.

This makes a copy of sys.path, appends any directories given as positional arguments, then reverts sys.path to the copied settings when the context ends.

Note that all sys.path modifications in the body of the context manager, including replacement of the object, will be reverted at the end of the block.

Parameters:
*paths: str

Directory paths to temporarily add to sys.path.

Examples:

with DirsOnSysPath("/tmp/my_modules"):
    import my_module
original_value : list[str] = "['/home/docs/checkouts/readthedocs.org/user_builds/standard-deluxe/checkouts/latest/src',..."
original_object : list[str] = "['/home/docs/checkouts/readthedocs.org/user_builds/standard-deluxe/checkouts/latest/src',..."
class Module(name: str, *, package: str = '', where: pathlib.Path | None = None)[source]

Utility class for dynamic loading of a Python module.

This class wraps the importlib machinery to resolve a module specification and load it from an explicit filesystem location or the default search path. It tracks the module’s package hierarchy and provides helper methods for comparing module names.

Parameters:
name: str

The module name to resolve. Can be a relative name (e.g. "foo") which is resolved against package.

package: str = ''

The package context for resolving relative module names. Default: "".

where: pathlib.Path | None = None

An explicit directory to search for the module. If None, the standard importlib.util.find_spec() search is used. Default: None.

Raises:

ModuleNotFoundError – If the module cannot be found.

Examples:

mod = Module("my_package.my_module")
mod.load()
print(mod.full_name)  # "my_package.my_module"
property pkg : str

Returns the package name this module belongs to.

property root : str

Returns the top package name this module belongs to.

property name : str

Returns the name of this module without any prefixes.

property full_name : str

Returns the full name of this module.

property module : types.ModuleType | None

Return the actual Module if loaded or None otherwise.

property is_package : bool

Returns True if this module is also a package.

property is_root : bool

Returns True if this module is a top package.

load() None[source]

Load this module if not already loaded.

The module is executed and registered in sys.modules. If the module is a submodule, it is also set as an attribute on its parent package.

Raises:
prefix_of(other: str) bool[source]

Check if this module is a package prefix of another module name.

Returns True only if this module is a package and other is a direct submodule of it (not the package itself).

Parameters:
other: str

The module name to test against.

Returns:

boolTrue if other is a submodule of this package.

share_root(other: str) bool[source]

Check if this module and another name share a common root package.

Two module names share a root if their first dotted component is the same and nonempty.

Parameters:
other: str

The module name to compare against.

Returns:

boolTrue if both names share the same top-level package prefix.

class monkey(*, module: str, target: str)[source]

Decorator-based monkey patcher for module attributes.

This class provides a declarative way to register monkey patches. Each patch is defined by decorating a replacement function with a monkey instance. Patches are stored globally and applied together via apply_all().

When a patch is applied, the original attribute value is saved and can be retrieved later via target(). Already-loaded modules that depend on the patched module are automatically marked for reload.

Protected modules (sys, builtins, importlib, importlib.util, __main__) cannot be patched or reloaded.

Parameters:
module: str

The fully qualified name of the module containing the attribute to patch.

target: str

The name of the attribute to replace.

Examples:

@monkey(module="os.path", target="join")
def patched_join(*args):
    return "patched"

monkey.apply_all()
classmethod patches() list[str][source]

Return a list of all registered patched target names.

Each name has the format "module.target".

Returns:

list[str] – The registered patch target names.

classmethod apply_all() None[source]

Apply all registered patches and reload affected modules.

Each patch is applied at most once. After all patches are applied, any modules marked for reload are re-imported.

Raises:

RuntimeError – If a protected module is encountered during the reload phase.

classmethod target(name: str) Patchable[source]

Return the original unpatched target of a registered patch.

Parameters:
name: str

The patch target name in the format "module.target".

Returns:

Patchable – The original attribute value before patching.

Raises:
  • RuntimeError – If called before any patch was applied.

  • KeyError – If name is not a registered patch.

classmethod marks_modules(*modules: str) None[source]

Mark module names for explicit reload during apply_all().

This is useful when a module’s behavior depends on a patched dependency but is not automatically detected by the patching mechanism.

Parameters:
*modules: str

Fully qualified module names to mark.

Raises:

ValueError – If a module is in the protected list (sys, builtins, importlib, importlib.util, or __main__).