chore: initial import
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Import-Helfer für Plugins.
|
||||
|
||||
Die eingebundenen Tools sind eigenständig gewachsen und benutzen deshalb
|
||||
naheliegende Modulnamen (app.py, storage.py, models.py …). Würden sie normal
|
||||
importiert, käme sich das zweite Tool mit dem ersten ins Gehege.
|
||||
|
||||
Diese Helfer laden ein Modul bzw. ein Paket unter einem eindeutigen Namen
|
||||
direkt aus dem Plugin-Ordner. Die Tools selbst müssen dafür nichts ändern:
|
||||
paketinterne Importe (from .auth import ...) funktionieren unverändert.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
|
||||
def load_module(file: Path, alias: str) -> ModuleType:
|
||||
"""Lädt eine einzelne .py-Datei unter eindeutigem Namen."""
|
||||
file = Path(file)
|
||||
if not file.is_file():
|
||||
raise FileNotFoundError(f"{file} fehlt")
|
||||
if alias in sys.modules:
|
||||
return sys.modules[alias]
|
||||
|
||||
spec = importlib.util.spec_from_file_location(alias, file)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"{file} kann nicht geladen werden")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[alias] = module
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
except Exception:
|
||||
sys.modules.pop(alias, None)
|
||||
raise
|
||||
return module
|
||||
|
||||
|
||||
def load_package(directory: Path, alias: str) -> ModuleType:
|
||||
"""Lädt ein Paket-Verzeichnis (mit __init__.py) unter eindeutigem Namen."""
|
||||
directory = Path(directory)
|
||||
init = directory / "__init__.py"
|
||||
if not init.is_file():
|
||||
raise FileNotFoundError(f"{init} fehlt")
|
||||
if alias in sys.modules:
|
||||
return sys.modules[alias]
|
||||
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
alias, init, submodule_search_locations=[str(directory)]
|
||||
)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"{directory} kann nicht geladen werden")
|
||||
package = importlib.util.module_from_spec(spec)
|
||||
sys.modules[alias] = package
|
||||
try:
|
||||
spec.loader.exec_module(package)
|
||||
except Exception:
|
||||
sys.modules.pop(alias, None)
|
||||
raise
|
||||
return package
|
||||
|
||||
|
||||
def load_submodule(directory: Path, package_alias: str, submodule: str) -> ModuleType:
|
||||
"""Lädt <directory>/<submodule>.py als Teil des Pakets <package_alias>."""
|
||||
load_package(directory, package_alias)
|
||||
return importlib.import_module(f"{package_alias}.{submodule}")
|
||||
Reference in New Issue
Block a user