Import all public submodules under the given package.
(package_name: str,
include: Optional[Set[str]] = None,
exclude: Optional[Set[str]] = None)
| 238 | |
| 239 | |
| 240 | def import_module_and_submodules(package_name: str, |
| 241 | include: Optional[Set[str]] = None, |
| 242 | exclude: Optional[Set[str]] = None) -> None: |
| 243 | """ |
| 244 | Import all public submodules under the given package. |
| 245 | """ |
| 246 | # take care of None |
| 247 | include = include if include else set() |
| 248 | exclude = exclude if exclude else set() |
| 249 | |
| 250 | def fn_in(package_name: str, pattern_set: Set[str]) -> bool: |
| 251 | for pattern in pattern_set: |
| 252 | if fnmatch(package_name, pattern): |
| 253 | return True |
| 254 | return False |
| 255 | |
| 256 | if not fn_in(package_name, include) and fn_in(package_name, exclude): |
| 257 | return |
| 258 | |
| 259 | importlib.invalidate_caches() |
| 260 | |
| 261 | # For some reason, python doesn't always add this by default to your path, but you pretty much |
| 262 | # always want it when using `--include-package`. And if it's already there, adding it again at |
| 263 | # the end won't hurt anything. |
| 264 | with push_python_path('.'): |
| 265 | # Import at top level |
| 266 | try: |
| 267 | module = importlib.import_module(package_name) |
| 268 | path = getattr(module, '__path__', []) |
| 269 | path_string = '' if not path else path[0] |
| 270 | |
| 271 | # walk_packages only finds immediate children, so need to recurse. |
| 272 | for module_finder, name, _ in pkgutil.iter_modules(path): |
| 273 | # Sometimes when you import third-party libraries that are on your path, |
| 274 | # `pkgutil.walk_packages` returns those too, so we need to skip them. |
| 275 | # `pkgutil.iter_modules` avoid import those package |
| 276 | if path_string and module_finder.path != path_string: # type: ignore[union-attr] |
| 277 | continue |
| 278 | if name.startswith('_'): |
| 279 | # skip directly importing private subpackages |
| 280 | continue |
| 281 | if name.startswith('test'): |
| 282 | # skip tests |
| 283 | continue |
| 284 | subpackage = f'{package_name}.{name}' |
| 285 | import_module_and_submodules( |
| 286 | subpackage, include=include, exclude=exclude) |
| 287 | except SystemExit as e: |
| 288 | # this case is specific for easy_cv's tools/predict.py exit |
| 289 | logger.warning( |
| 290 | f'{package_name} not imported: {str(e)}, but should continue') |
| 291 | pass |
| 292 | except Exception as e: |
| 293 | logger.warning(f'{package_name} not imported: {str(e)}') |
| 294 | if len(package_name.split('.')) == 1: |
| 295 | raise ModuleNotFoundError('Package not installed') |
| 296 | |
| 297 |
no test coverage detected
searching dependent graphs…