commit 9cea034fc30df3dbe9184975074f2b53cb4c7500 Author: hhh Date: Fri Feb 2 22:36:53 2024 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e08268f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/.idea/ +/tests/ + +poetry.lock + +*/__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..4267334 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +[nekomata is now in early-dev state](https://nekomata.kotikot.com/) diff --git a/neko_injector/__init__.py b/neko_injector/__init__.py new file mode 100644 index 0000000..d3d82e9 --- /dev/null +++ b/neko_injector/__init__.py @@ -0,0 +1,14 @@ +from .neko.interfaces import ( + inject_module, + inject_modules, + inject_object, + get_injected_object +) + + +__all__ = [ + 'inject_module', + 'inject_modules', + 'inject_object', + 'get_injected_object' +] diff --git a/neko_injector/modules/__init__.py b/neko_injector/modules/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/neko_injector/modules/__init__.py @@ -0,0 +1 @@ +pass diff --git a/neko_injector/modules/applyer.py b/neko_injector/modules/applyer.py new file mode 100644 index 0000000..47957c1 --- /dev/null +++ b/neko_injector/modules/applyer.py @@ -0,0 +1,32 @@ +import importlib +from typing import TypeVar +from types import ModuleType + +from ..neko.integrations import neko_config + + +T = TypeVar('T') + + +def apply_replace(obj: T) -> T: + if isinstance(obj, ModuleType): + module = obj.__package__ + if obj.__name__ == obj.__package__: + module = module.split('.')[0] + name = obj.__name__.removeprefix(module).removeprefix('.') + elif issubclass(obj, object): + module = obj.__module__ + name = obj.__name__ + else: + raise ImportError(f'Cannot apply import patches to type {type(obj)}') + + try: + return importlib.import_module( + neko_config.connections[module.split('.')[0]] + + module.removeprefix(module.split('.')[0]) + ).__getattribute__(name) + except (AttributeError, KeyError): + raise ImportError( + f'No standard--implementation connection for ' + f'{module.split(".")[0]}' + ) diff --git a/neko_injector/modules/variants.py b/neko_injector/modules/variants.py new file mode 100644 index 0000000..47884a2 --- /dev/null +++ b/neko_injector/modules/variants.py @@ -0,0 +1,37 @@ +from .applyer import apply_replace + +from typing import Iterable, Type, TypeVar +from types import ModuleType + + +T = TypeVar('T') + + +def inject_object(*objects) -> None: + for obj in objects: + new = apply_replace(obj) + for attr, value in new.__dict__.items(): + try: + setattr(obj, attr, getattr(new, attr)) + except AttributeError: + continue + + +def get_injected_object(*objects: Type[T]) -> Iterable[T]: + return [apply_replace(obj) for obj in objects] + + +def inject_module(mod: ModuleType) -> None: + try: + inject_object(*getattr(mod, '__replacements__')) + except AttributeError: + raise ImportError(f'Module {mod.__name__} does not define a list of ' + f'replacements, it cannot be patched') + except ModuleNotFoundError: + raise ImportError(f'The implementation presented in the config does not comply ' + f'with the structure of the standard') + + +def inject_modules(modules: list[ModuleType]) -> None: + for module in modules: + inject_module(module) diff --git a/neko_injector/neko/__init__.py b/neko_injector/neko/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/neko_injector/neko/integrations.py b/neko_injector/neko/integrations.py new file mode 100644 index 0000000..02e7418 --- /dev/null +++ b/neko_injector/neko/integrations.py @@ -0,0 +1,7 @@ +from neko_configparser import ConfigParserInterface + + +neko_config = ConfigParserInterface.parse_config() + + +__all__ = ['ConfigParserInterface', 'neko_config'] diff --git a/neko_injector/neko/interfaces.py b/neko_injector/neko/interfaces.py new file mode 100644 index 0000000..d0eac8a --- /dev/null +++ b/neko_injector/neko/interfaces.py @@ -0,0 +1,14 @@ +from ..modules.variants import ( + inject_module, + inject_modules, + inject_object, + get_injected_object +) + + +__all__ = [ + 'inject_module', + 'inject_modules', + 'inject_object', + 'get_injected_object' +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ff95a61 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[tool.poetry] +name = "neko-injector" +version = "0.1.0" +description = "" +authors = ["hhh"] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +neko-configparser = {git="https://github.com/nekomatad/neko-configparser"} +#neko-configparser = {path = "../neko-configparser", develop = true} + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"