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¶
Context manager to force import to return a… |
|
Context manager to temporarily add directories… |
|
Utility class for dynamic loading of a Python… |
|
Decorator-based monkey patcher for module… |
|
Load a Python module or package from a… |
|
Forget a module was ever imported. |
|
Import and return a module, deliberately… |
|
Force frozen modules to be used (or not). |
Type alias for objects that can be the target… |
|
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
Modulethat 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,Noneotherwise.- Raises:¶
ModuleNotFoundError – If the module cannot be found at the given path.
ImportError – If loading the module fails.
- forget_module(name: str) None[source]¶
Forget a module was ever imported.
This removes the module from
sys.modulesand deletes any PEP 3147/488 or legacy.pyccached bytecode files found alongsys.path.
- import_fresh_module(
- name: str,
- fresh: collections.abc.Iterable[str] =
(), - blocked: collections.abc.Iterable[str] =
(), - *,
- deprecated: bool =
False, - usefrozen: bool =
False, 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.modulesbefore doing the import. Note that unlikeimportlib.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.moduleswhen 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.modulescache before the import. If one of these modules cannot be imported,Noneis returned. Default:().- blocked: collections.abc.Iterable[str] =
()¶ Module names that are replaced with
Nonein the module cache during the import to ensure that attempts to import them raiseImportError. 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 likeimportlib._bootstrap). Default:False.
- Returns:¶
ModuleType|None– The freshly imported module, orNoneif 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.
-
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
DeprecationWarningon import.When entered, the named modules are removed from
sys.modulesso that subsequent imports return fresh references. On exit, the originalsys.modulesstate 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 likeimportlib._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 revertssys.pathto the copied settings when the context ends.Note that all
sys.pathmodifications in the body of the context manager, including replacement of the object, will be reverted at the end of the block.Examples:
with DirsOnSysPath("/tmp/my_modules"): import my_module
-
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
importlibmachinery 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 standardimportlib.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 module : types.ModuleType | None¶
Return the actual Module if loaded or None otherwise.
- 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:¶
ModuleNotFoundError – If the module specification cannot be found.
ImportError – If loading the module fails.
- prefix_of(other: str) bool[source]¶
Check if this module is a package prefix of another module name.
Returns
Trueonly if this module is a package and other is a direct submodule of it (not the package itself).
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.
The module name to compare against.
bool–Trueif 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
monkeyinstance. Patches are stored globally and applied together viaapply_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:¶
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".
- 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.
- 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:¶
- Raises:¶
ValueError – If a module is in the protected list (
sys,builtins,importlib,importlib.util, or__main__).