From 20517c1bb816b07b3f1520b81c22c1f33dd204a5 Mon Sep 17 00:00:00 2001 From: Winston Sung Date: Thu, 28 Nov 2024 02:17:38 +0800 Subject: [PATCH] Packaging: Prepare src layout migration - Dependency injection - Service container - Service wiring Change-Id: I058ef5706b803d8a415ab088559f893288ab7c48 --- src/scaict_uwu/language/language.py | 42 --------- src/scaict_uwu/language/language_tag.py | 26 ++++++ .../language/language_tag_factory.py | 26 ++++++ src/scaict_uwu/service_container.py | 91 +++++++++++++++++++ src/scaict_uwu/service_wiring.py | 16 ++++ src/scaict_uwu/system_message/message.py | 4 +- 6 files changed, 161 insertions(+), 44 deletions(-) delete mode 100644 src/scaict_uwu/language/language.py create mode 100644 src/scaict_uwu/language/language_tag.py create mode 100644 src/scaict_uwu/language/language_tag_factory.py create mode 100644 src/scaict_uwu/service_container.py create mode 100644 src/scaict_uwu/service_wiring.py diff --git a/src/scaict_uwu/language/language.py b/src/scaict_uwu/language/language.py deleted file mode 100644 index 9852656..0000000 --- a/src/scaict_uwu/language/language.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -This is the module for the class for all languages. -""" - - -class Language: - """ - The Language class deals with language data. - """ - - def get_bcp_47_lang_tag(self) -> str | None: - pass - - def get_bcp_47_lang_subtag(self) -> str | None: - pass - - def get_iso_639_lang_code(self) -> str | None: - pass - - def get_bcp_47_script_subtag(self) -> str | None: - pass - - def get_bcp_47_region_subtag(self) -> str | None: - pass - - def get_bcp_47_variant_subtags(self) -> list | None: - pass - - def get_bcp_47_private_subtags(self) -> list | None: - pass - - def get_writing_mode(self) -> str | None: - pass - - def get_writing_mode_dir(self) -> str | None: - pass - - def get_writing_mode_prop(self) -> str | None: - pass - - def get_lang_fallbacks(self) -> list | None: - pass diff --git a/src/scaict_uwu/language/language_tag.py b/src/scaict_uwu/language/language_tag.py new file mode 100644 index 0000000..bf8eb89 --- /dev/null +++ b/src/scaict_uwu/language/language_tag.py @@ -0,0 +1,26 @@ +""" +This is the module for the class for all languages. +""" + + +class LanguageTag: + """ + The LanguageTag class deals with language data. + """ + + _tag: str + """ + _tag (str): The BCP 47 language subtag of the LanguageTag object. + """ + + def __init__(self, language_tag) -> None: + pass + + def get_bcp_47_tag(self) -> str | None: + pass + + def get_discord_code(self) -> str | None: + pass + + def get_fallbacks(self) -> list | None: + pass diff --git a/src/scaict_uwu/language/language_tag_factory.py b/src/scaict_uwu/language/language_tag_factory.py new file mode 100644 index 0000000..ee04888 --- /dev/null +++ b/src/scaict_uwu/language/language_tag_factory.py @@ -0,0 +1,26 @@ +""" +This is the module for creating the objects for all languages. +""" + +# Local imports +from .language_tag import LanguageTag + + +class LanguageTagFactory: + """ + The LanguageTagFactory class deals with LanguageTag object creations. + """ + + _tags: dict = {} + """ + _tags (dict): The LanguageTag objects. + """ + + def __init__(self) -> None: + pass + + def get_tag(self) -> LanguageTag | None: + pass + + def get_tag_by_discord_code(self) -> LanguageTag | None: + pass diff --git a/src/scaict_uwu/service_container.py b/src/scaict_uwu/service_container.py new file mode 100644 index 0000000..740c709 --- /dev/null +++ b/src/scaict_uwu/service_container.py @@ -0,0 +1,91 @@ +""" +Module for SCAICT-uwu service locator. +""" + +# Standard imports +import importlib +import sys + + +class ServiceContainer: + """ + Service locator for SCAICT-uwu core services. + + Refer to service_wiring.py for the default implementations. + """ + + _services: dict = {} + """ + """ + + _service_instantiators: dict = {} + """ + """ + + _services_being_created: dict = {} + """ + """ + + def load_wiring_files(self, wiring_modules: list) -> None: + for module_name in wiring_modules: + module = importlib.import_module(module_name) + self.apply_wiring(module.get_wiring()) + + def apply_wiring(self, service_instantiators) -> None: + for name, instantiator in service_instantiators: + self.define_service(name, instantiator) + + def get_service_names(self) -> list: + # Convert dict_keys to list + return list(self._service_instantiators.keys()) + + def has_service(self, name: str) -> bool: + return name in self._service_instantiators + + def define_service(self, name: str, instantiator) -> None: + if self.has_service(name): + sys.exit("ServiceAlreadyDefinedException $name") + + self._service_instantiators[name] = instantiator + + def redefine_service(self, name: str, instantiator) -> None: + if not self.has_service(name): + sys.exit("NoSuchServiceException $name") + + if name in self._services: + sys.exit("CannotReplaceActiveServiceException $name") + + self._service_instantiators[name] = instantiator + + def create_service(self, name: str): + if not self.has_service(name): + sys.exit("NoSuchServiceException $name") + + if not name in self._services_being_created: + sys.exit( + "RecursiveServiceDependencyException " + + "Circular dependency when creating service!" + ) + + self._services_being_created[name] = True + + service = self._service_instantiators[name](self) + + return service + + def get_service(self, name: str): + if not name in self._services: + self._services[name] = self.create_service(name) + + return self._services[name] + + # Service helper functions + + def get_config(self): + return self.get_service("Config") + + def get_language_tag(self): + return self.get_service("LanguageTag") + + def get_language_tag_factory(self): + return self.get_service("LanguageTagFactory") diff --git a/src/scaict_uwu/service_wiring.py b/src/scaict_uwu/service_wiring.py new file mode 100644 index 0000000..f885323 --- /dev/null +++ b/src/scaict_uwu/service_wiring.py @@ -0,0 +1,16 @@ +""" +Module for SCAICT-uwu default service implementations. +""" + +from .service_container import ServiceContainer + + +def get_wiring() -> dict: + """ + Get the service implementation functions. + """ + return {"Config": get_config} + + +def get_config(service_container: ServiceContainer): + pass diff --git a/src/scaict_uwu/system_message/message.py b/src/scaict_uwu/system_message/message.py index 96744fe..4466053 100644 --- a/src/scaict_uwu/system_message/message.py +++ b/src/scaict_uwu/system_message/message.py @@ -3,7 +3,7 @@ """ # Local imports -from ..language.language import Language +from ..language.language_tag import LanguageTag class Message: @@ -27,7 +27,7 @@ def __init__( self, key: str, params: list, - use_lang: Language | None, + use_lang: LanguageTag | None, ) -> None: """ Set the language tag of the language that the message expected to use.