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.")
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:
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.
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: