hojichar.utils.load_compose

  1from __future__ import annotations
  2
  3import importlib.util
  4import logging
  5import sys
  6from os import PathLike
  7from pathlib import Path
  8from types import ModuleType
  9from typing import Any, Callable, Optional, Union
 10
 11import hojichar
 12
 13logger = logging.getLogger(__name__)
 14
 15
 16def _load_module(path: Union[str, PathLike]) -> ModuleType:
 17    # HACK type hint `os.PathLike[str]` is not allowed in Python 3.8 or older.
 18    # So I write Union[str, PathLike]
 19    path_obj = Path(path)
 20    module_name = path_obj.stem
 21    spec = importlib.util.spec_from_file_location(module_name, path_obj)
 22    if spec and spec.loader:
 23        module = importlib.util.module_from_spec(spec)
 24        sys.modules[module_name] = module
 25        spec.loader.exec_module(module)
 26    return module
 27
 28
 29def load_filter_from_file(
 30    profile_path: Union[str, PathLike],
 31) -> hojichar.Compose | hojichar.AsyncCompose:
 32    """
 33    Loading a profile which has `FILTER` variable.
 34    Given path is added to sys.path automaticaly.
 35
 36    Args:
 37        profile_path (str): Path to a Python file that implements custom filter
 38        hojichar.Compose must be defined as FILTER variable in the file.
 39
 40    Raises:
 41        NotImplementedError:
 42
 43    Returns:
 44        hojichar.Compose | hojichar.AsyncCompose:
 45    """
 46    sys.path.append(str(Path(profile_path).parent))
 47    module = _load_module(profile_path)
 48    if hasattr(module, "FILTER"):
 49        filter = getattr(module, "FILTER")
 50        if not isinstance(filter, (hojichar.Compose, hojichar.AsyncCompose)):
 51            raise TypeError("FILTER must be Compose or AsyncCompose object.")
 52        return filter
 53    else:
 54        raise NotImplementedError("FILTER is not defined in the profile.")
 55
 56
 57def load_factory_from_file(
 58    profile_path: Union[str, PathLike],
 59) -> Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose]:
 60    """
 61    Loading a function by a profile which has `FACTORY` variable.
 62    Given path is added to sys.path automaticaly.
 63
 64    Args:
 65        profile_path (PathLike): Path to a Python file that implements custom filter
 66
 67    Raises:
 68        NotImplementedError:
 69
 70    Returns:
 71        Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose]:
 72            An alias of the function which returns Compose or AsyncCompose.
 73    """
 74    sys.path.append(str(Path(profile_path).parent))
 75    module = _load_module(profile_path)
 76    if hasattr(module, "FACTORY"):
 77        factory: Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose] = getattr(
 78            module, "FACTORY"
 79        )
 80        return factory
 81    else:
 82        raise NotImplementedError("FACTORY is not defined in the profile")
 83
 84
 85def load_parametrized_filter_from_file(
 86    profile_path: Union[str, PathLike], *factory_args: str
 87) -> hojichar.Compose | hojichar.AsyncCompose:
 88    factory = load_factory_from_file(profile_path)
 89    filter = factory(*factory_args)
 90    return filter
 91
 92
 93def load_compose(
 94    profile_path: Union[str, PathLike], *factory_args: str
 95) -> hojichar.Compose | hojichar.AsyncCompose:
 96    """
 97    Loading a Compose file from profile. Loading a Compose file from the profile.
 98    Both `FILTER` and `FACTORY` pattern of the profile is loaded.
 99
100    Args:
101        profile_path (PathLike):
102
103    Returns:
104        hojichar.Compose:
105    """
106    try:
107        filter = load_filter_from_file(profile_path)
108        _check_args_num_mismatch(len(factory_args))
109        return filter
110    except NotImplementedError:
111        return load_parametrized_filter_from_file(profile_path, *factory_args)
112
113
114def _check_args_num_mismatch(num_args: int) -> None:
115    if num_args > 0:
116        logger.warning(f"Warning: {num_args} arguments are ignored.")
def load_filter_from_file( profile_path: Union[str, os.PathLike]) -> hojichar.core.composition.Compose | hojichar.core.async_composition.AsyncCompose:
30def load_filter_from_file(
31    profile_path: Union[str, PathLike],
32) -> hojichar.Compose | hojichar.AsyncCompose:
33    """
34    Loading a profile which has `FILTER` variable.
35    Given path is added to sys.path automaticaly.
36
37    Args:
38        profile_path (str): Path to a Python file that implements custom filter
39        hojichar.Compose must be defined as FILTER variable in the file.
40
41    Raises:
42        NotImplementedError:
43
44    Returns:
45        hojichar.Compose | hojichar.AsyncCompose:
46    """
47    sys.path.append(str(Path(profile_path).parent))
48    module = _load_module(profile_path)
49    if hasattr(module, "FILTER"):
50        filter = getattr(module, "FILTER")
51        if not isinstance(filter, (hojichar.Compose, hojichar.AsyncCompose)):
52            raise TypeError("FILTER must be Compose or AsyncCompose object.")
53        return filter
54    else:
55        raise NotImplementedError("FILTER is not defined in the profile.")

Loading a profile which has FILTER variable. Given path is added to sys.path automaticaly.

Args: profile_path (str): Path to a Python file that implements custom filter hojichar.Compose must be defined as FILTER variable in the file.

Raises: NotImplementedError:

Returns: hojichar.Compose | hojichar.AsyncCompose:

def load_factory_from_file( profile_path: Union[str, os.PathLike]) -> Callable[[Optional[Any]], hojichar.core.composition.Compose | hojichar.core.async_composition.AsyncCompose]:
58def load_factory_from_file(
59    profile_path: Union[str, PathLike],
60) -> Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose]:
61    """
62    Loading a function by a profile which has `FACTORY` variable.
63    Given path is added to sys.path automaticaly.
64
65    Args:
66        profile_path (PathLike): Path to a Python file that implements custom filter
67
68    Raises:
69        NotImplementedError:
70
71    Returns:
72        Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose]:
73            An alias of the function which returns Compose or AsyncCompose.
74    """
75    sys.path.append(str(Path(profile_path).parent))
76    module = _load_module(profile_path)
77    if hasattr(module, "FACTORY"):
78        factory: Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose] = getattr(
79            module, "FACTORY"
80        )
81        return factory
82    else:
83        raise NotImplementedError("FACTORY is not defined in the profile")

Loading a function by a profile which has FACTORY variable. Given path is added to sys.path automaticaly.

Args: profile_path (PathLike): Path to a Python file that implements custom filter

Raises: NotImplementedError:

Returns: Callable[[Optional[Any]], hojichar.Compose | hojichar.AsyncCompose]: An alias of the function which returns Compose or AsyncCompose.

def load_parametrized_filter_from_file( profile_path: Union[str, os.PathLike], *factory_args: str) -> hojichar.core.composition.Compose | hojichar.core.async_composition.AsyncCompose:
86def load_parametrized_filter_from_file(
87    profile_path: Union[str, PathLike], *factory_args: str
88) -> hojichar.Compose | hojichar.AsyncCompose:
89    factory = load_factory_from_file(profile_path)
90    filter = factory(*factory_args)
91    return filter
def load_compose( profile_path: Union[str, os.PathLike], *factory_args: str) -> hojichar.core.composition.Compose | hojichar.core.async_composition.AsyncCompose:
 94def load_compose(
 95    profile_path: Union[str, PathLike], *factory_args: str
 96) -> hojichar.Compose | hojichar.AsyncCompose:
 97    """
 98    Loading a Compose file from profile. Loading a Compose file from the profile.
 99    Both `FILTER` and `FACTORY` pattern of the profile is loaded.
100
101    Args:
102        profile_path (PathLike):
103
104    Returns:
105        hojichar.Compose:
106    """
107    try:
108        filter = load_filter_from_file(profile_path)
109        _check_args_num_mismatch(len(factory_args))
110        return filter
111    except NotImplementedError:
112        return load_parametrized_filter_from_file(profile_path, *factory_args)

Loading a Compose file from profile. Loading a Compose file from the profile. Both FILTER and FACTORY pattern of the profile is loaded.

Args: profile_path (PathLike):

Returns: hojichar.Compose: