stubpy.loader¶
stubpy.loader¶
Dynamic module loading for stub generation.
Provides load_module(), which imports a .py file as a live
Python module so that inspect and typing.get_type_hints()
can introspect its classes and annotations at runtime.
- load_module(filepath: str) tuple[ModuleType, Path, str][source]¶
Dynamically load a Python source file as an importable module.
Temporarily extends
sys.pathwith the file’s parent directory and its grandparent so that package-relative imports inside the target resolve correctly. Both paths are always removed in afinallyblock regardless of errors.- Parameters:
filepath (str) – Path to the
.pysource file. Relative paths are resolved against the current working directory.- Returns:
module (types.ModuleType) – The fully initialised module object.
resolved_path (pathlib.Path) – Absolute path of the source file.
module_name (str) – Synthetic name used to register the module in
sys.modules, of the form_stubpy_target_<stem>.
- Raises:
FileNotFoundError – If filepath does not exist on disk.
ImportError – If
importlib.util.spec_from_file_location()cannot create a module spec for the file.
Examples
>>> module, path, name = load_module("mypackage/shapes.py") >>> path.suffix '.py' >>> name.startswith("_stubpy_target_") True
sys.path management
load_module() temporarily adds two directories to sys.path:
The file’s own parent directory (e.g.
mypackage/shapes/)The grandparent directory (e.g.
mypackage/)
This lets files in a sub-package do from mypackage import types
without requiring the package to be installed. Both paths are removed in
a finally block — the caller’s sys.path is always restored.
Module naming
The synthetic module name has the form _stubpy_target_<stem> where
<stem> is the source filename without extension. This is unlikely to
collide with real module names and is deterministic across runs.