Skip to content

Modules

src.utils.modules._add_python_path(path: Union[str, os.PathLike]) -> None

Add a path to 'sys.path' to allow relative import discovery.

Parameters:

Name Type Description Default
path str | PathLike

Path containing a module which needs relative import behavior.

required
Source code in src\utils\modules.py
18
19
20
21
22
23
24
25
26
def _add_python_path(path: Union[str, os.PathLike]) -> None:
    """Add a path to 'sys.path' to allow relative import discovery.

    Args:
        path: Path containing a module which needs relative import behavior.
    """
    p = str(path)
    if p not in sys.path:
        sys.path.append(p)

src.utils.modules._remove_python_path(path: Union[str, os.PathLike]) -> None

Remove a path to 'sys.path' to keep the namespace clean.

Parameters:

Name Type Description Default
path str | PathLike

Path containing a module which needs relative import behavior.

required
Source code in src\utils\modules.py
29
30
31
32
33
34
35
36
37
def _remove_python_path(path: Union[str, os.PathLike]) -> None:
    """Remove a path to 'sys.path' to keep the namespace clean.

    Args:
        path: Path containing a module which needs relative import behavior.
    """
    p = str(path)
    if p in sys.path:
        sys.path.remove(p)

src.utils.modules.import_package(name: str, path: Path, hotswap: bool = False) -> Optional[ModuleType]

Loads a module package using importlib or from 'sys.modules', allowing for forced reloads.

Parameters:

Name Type Description Default
name str

Name of the module.

required
path Path

Path to the module.

required
hotswap bool

Whether to force the module to be reloaded fresh.

False

Returns:

Type Description
ModuleType | None

The loaded module.

Source code in src\utils\modules.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def import_package(name: str, path: Path, hotswap: bool = False) -> Optional[ModuleType]:
    """Loads a module package using importlib or from 'sys.modules', allowing for forced reloads.

    Args:
        name: Name of the module.
        path: Path to the module.
        hotswap: Whether to force the module to be reloaded fresh.

    Returns:
        The loaded module.
    """
    # Return previously loaded module
    if name in sys.modules:
        if not hotswap:
            return sys.modules[name]
        del sys.modules[name]

    # Add parent folder to path
    _add_python_path(str(path))

    # Collect nested modules before importing and executing
    import_nested_modules(
        name=name,
        path=path,
        recursive=True,
        hotswap=hotswap,
        ignored=['__init__.py'])

    # Return None if init module not found
    init_module = path / '__init__.py'
    if not init_module.is_file():
        _remove_python_path(str(path))
        return

    # Import and execute the init module
    module = import_module_from_path(name=name, path=init_module, hotswap=hotswap)

    # Reset system paths and return
    _remove_python_path(str(path))
    return module

src.utils.modules.import_nested_modules(name: str, path: Path, recursive: bool = True, hotswap: bool = False, ignored: Optional[list[str]] = None) -> None

Imports modules nested inside a directory.

Source code in src\utils\modules.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def import_nested_modules(
    name: str,
    path: Path,
    recursive: bool = True,
    hotswap: bool = False,
    ignored: Optional[list[str]] = None
) -> None:
    """Imports modules nested inside a directory."""
    ignored = ignored or []
    for item in os.listdir(path):
        if item in ['__pycache__', *ignored]:
            continue
        p = path / item
        n = '.'.join([name, p.stem])
        if p.is_dir() and recursive:
            # Import directory
            _add_python_path(str(p))
            import_nested_modules(
                name=n, path=p, hotswap=hotswap, ignored=ignored)
            _remove_python_path(str(p))
            continue
        elif p.is_file():
            # Import module
            import_module_from_path(name=n, path=p, hotswap=hotswap)

src.utils.modules.import_module_from_path(name: str, path: Path, hotswap: bool = False) -> ModuleType

Import a module from a given path.

Parameters:

Name Type Description Default
name str

Name of the module.

required
path Path

Path to the module.

required
hotswap bool

Whether to

False

Returns:

Type Description
ModuleType

Loaded and executed module.

Source code in src\utils\modules.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def import_module_from_path(name: str, path: Path, hotswap: bool = False) -> ModuleType:
    """Import a module from a given path.

    Args:
        name: Name of the module.
        path: Path to the module.
        hotswap: Whether to

    Returns:
        Loaded and executed module.
    """
    # Return previously loaded module
    if name in sys.modules:
        if not hotswap:
            return sys.modules[name]
        del sys.modules[name]

    # Import and execute the module
    spec = spec_from_file_location(name=name, location=path)
    module = module_from_spec(spec)
    spec.loader.exec_module(module)
    sys.modules[name] = module
    return module

src.utils.modules.get_local_module(module_path: str, hotswap: bool = False) -> ModuleType

Lookup a local module by its module path, forcing a reload if hotswap enabled.

Parameters:

Name Type Description Default
module_path str

Path to the module in module notation, e.g. "src.templates"

required
hotswap bool

If True, always load module fresh.

False

Returns:

Name Type Description
ModuleType ModuleType

Loaded module.

Raises:

Type Description
ImportError

If module couldn't be loaded successfully.

Source code in src\utils\modules.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
def get_local_module(module_path: str, hotswap: bool = False) -> ModuleType:
    """Lookup a local module by its module path, forcing a reload if hotswap enabled.

    Args:
        module_path: Path to the module in module notation, e.g. "src.templates"
        hotswap: If True, always load module fresh.

    Returns:
        ModuleType: Loaded module.

    Raises:
        ImportError: If module couldn't be loaded successfully.
    """

    # Check if the module has already been loaded
    if module_path in sys.modules:
        if not hotswap:
            return sys.modules[module_path]
        del sys.modules[module_path]

    # Load the module fresh and cache it
    module = importlib.import_module(module_path)
    sys.modules[module_path] = module
    return module