mongo/buildscripts/resmokelib/utils/autoloader.py
Trevor Guidry 6fa6d77e0b SERVER-121737 Add fixture and hook support to external resmoke modules (#49689)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
GitOrigin-RevId: ed84084a285fbfdb493480f5a5a6b633c703017f
2026-03-17 14:54:06 +00:00

57 lines
2.1 KiB
Python

"""Utility for loading all modules within a package."""
import importlib
import os
import pkgutil
import sys
import types
def load_all_modules(name: str, path: list[str]) -> None:
"""Dynamically load all modules in the 'name' package.
This function is useful in combination with the registry.py module
so that any classes declared within the package are automatically
registered.
The following is the intended usage within the __init__.py file for
a package:
from utils import autoloader as _autoloader
_autoloader.load_all_modules(name=__name__, path=__path__)
"""
# If package doesn't exist yet, ensure all parent packages are created
if name not in sys.modules:
parts = name.split(".")
for i in range(len(parts)):
parent = ".".join(parts[: i + 1])
if parent not in sys.modules:
# Create a synthetic module for the parent package
parent_module = types.ModuleType(parent)
parent_module.__package__ = parent
# Set __path__ to make it a proper package that can contain submodules
# Derive parent path by going up the directory tree
if parent == name:
# Target package gets the provided path
parent_module.__path__ = path
else:
# Parent packages get paths derived from the target path
# Calculate how many levels up we need to go
levels_up = len(parts) - (i + 1)
parent_paths = []
for p in path:
# Go up 'levels_up' directories from the target path
parent_path = p
for _ in range(levels_up):
parent_path = os.path.dirname(parent_path)
parent_paths.append(parent_path)
parent_module.__path__ = parent_paths
sys.modules[parent] = parent_module
for _, module, _ in pkgutil.walk_packages(path=path):
importlib.import_module("." + module, package=name)