Mini Shell
"""
Provides utilities for dynamically loading packages/modules.
"""
import importlib
import importlib.util
import logging
import os
import pkgutil
import sys
from pathlib import Path
from typing import Generator, List, Union
logger = logging.getLogger(__name__)
def get_module_by_path(
module_name: str, file_path: Union[str, Path]
) -> "module":
"""
Execute and return module from *file_path*
"""
# https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def iter_modules(
paths: List[Union[str, Path]]
) -> Generator["module", None, None]:
"""
Yields all modules from *paths*
"""
for module in pkgutil.iter_modules(paths):
if not module.ispkg:
path = Path(module.module_finder.path) / f"{module.name}.py"
yield get_module_by_path(module.name, path)
def load(name: str, missing_ok=False) -> None:
"""
Import *name* module, if *name* is a package import all submodules.
If *name* module/package is not found:
- raise ModuleNotFoundError if *missing_ok* is False
- ignore it if *missing_ok* is True
"""
try:
spec = importlib.util.find_spec(name)
except ModuleNotFoundError:
if not missing_ok:
raise
return
# import *name* itself, for package it is __init__.py
importlib.import_module(name)
if spec.loader.is_package(spec.name):
package = name
for module in pkgutil.iter_modules(spec.submodule_search_locations):
importlib.import_module(f"{package}.{module.name}")
def load_packages(packages: tuple, missing_ok=False) -> None:
for package in packages:
load(package, missing_ok=missing_ok)
def get(*, module, name, default):
"""
Return object with *name* from specific *module*.
If object was not found return *default*
"""
try:
m = importlib.import_module(module)
except ModuleNotFoundError:
return default
return getattr(m, name, default)
def exists(name):
try:
spec = importlib.util.find_spec(name)
except ModuleNotFoundError:
return False
return spec is not None
Zerion Mini Shell 1.0