Source code for redditwarp.util.imports


from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
if TYPE_CHECKING:
    from types import ModuleType
    from importlib.machinery import ModuleSpec
    from os import PathLike

import sys
import importlib.util


[docs]def load_spec(name: str, package: Optional[str] = None) -> ModuleSpec: spec = importlib.util.find_spec(name, package) if spec is None: raise RuntimeError(f'module spec not found: {name} ({package})') return spec
[docs]def load_spec_from_file_location(name: str, location: Union[str, bytes, PathLike[str], PathLike[bytes]]) -> ModuleSpec: spec = importlib.util.spec_from_file_location(name, location) if spec is None: raise RuntimeError(f'module spec not found: {name} ({str(location)})') return spec
[docs]def import_module_from_spec(spec: ModuleSpec) -> ModuleType: if spec.loader is None: raise RuntimeError('spec has no loader') module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module
[docs]class LazyImport: """An object for lazily loading modules.""" def __call__(self, name: str, package: Optional[str] = None) -> ModuleType: try: return sys.modules[name] except KeyError: spec = importlib.util.find_spec(name, package) if spec is None: raise RuntimeError(f'module named {name!r} not found') if spec.loader is None: raise RuntimeError('spec has no loader') loader = importlib.util.LazyLoader(spec.loader) spec.loader = loader return import_module_from_spec(spec) def __mod__(self, other: str) -> None: if '.' in other: raise ValueError('dotted module name not supported') module = self(other) caller_frame = sys._getframe(1) # type: ignore caller_frame.f_globals[other] = module
lazy_import: LazyImport = LazyImport()