|
16 | 16 | import os
|
17 | 17 | import pdb
|
18 | 18 | import re
|
| 19 | +import sys |
19 | 20 | import warnings
|
20 | 21 | from collections.abc import Callable, Collection, Hashable, Mapping
|
21 | 22 | from functools import partial, wraps
|
22 | 23 | from importlib import import_module
|
| 24 | +from pkgutil import walk_packages |
23 | 25 | from pydoc import locate
|
24 | 26 | from re import match
|
25 |
| -from types import FunctionType |
| 27 | +from types import FunctionType, ModuleType |
26 | 28 | from typing import Any, Iterable, cast
|
27 | 29 |
|
28 | 30 | import torch
|
@@ -168,6 +170,38 @@ def damerau_levenshtein_distance(s1: str, s2: str) -> int:
|
168 | 170 | return d[string_1_length - 1, string_2_length - 1]
|
169 | 171 |
|
170 | 172 |
|
| 173 | +def load_submodules( |
| 174 | + basemod: ModuleType, load_all: bool = True, exclude_pattern: str = "(.*[tT]est.*)|(_.*)" |
| 175 | +) -> tuple[list[ModuleType], list[str]]: |
| 176 | + """ |
| 177 | + Traverse the source of the module structure starting with module `basemod`, loading all packages plus all files if |
| 178 | + `load_all` is True, excluding anything whose name matches `exclude_pattern`. |
| 179 | + """ |
| 180 | + submodules = [] |
| 181 | + err_mod: list[str] = [] |
| 182 | + for importer, name, is_pkg in walk_packages( |
| 183 | + basemod.__path__, prefix=basemod.__name__ + ".", onerror=err_mod.append |
| 184 | + ): |
| 185 | + if (is_pkg or load_all) and name not in sys.modules and match(exclude_pattern, name) is None: |
| 186 | + try: |
| 187 | + mod = import_module(name) |
| 188 | + mod_spec = importer.find_spec(name) # type: ignore |
| 189 | + if mod_spec and mod_spec.loader: |
| 190 | + loader = mod_spec.loader |
| 191 | + loader.exec_module(mod) |
| 192 | + submodules.append(mod) |
| 193 | + except OptionalImportError: |
| 194 | + pass # could not import the optional deps., they are ignored |
| 195 | + except ImportError as e: |
| 196 | + msg = ( |
| 197 | + "\nMultiple versions of MONAI may have been installed?\n" |
| 198 | + "Please see the installation guide: https://docs.monai.io/en/stable/installation.html\n" |
| 199 | + ) # issue project-monai/monai#5193 |
| 200 | + raise type(e)(f"{e}\n{msg}").with_traceback(e.__traceback__) from e # raise with modified message |
| 201 | + |
| 202 | + return submodules, err_mod |
| 203 | + |
| 204 | + |
171 | 205 | def instantiate(__path: str, __mode: str, **kwargs: Any) -> Any:
|
172 | 206 | """
|
173 | 207 | Create an object instance or call a callable object from a class or function represented by ``_path``.
|
|
0 commit comments