import logging from typing import Optional from yaml import safe_load class I18N: def __init__(self, logger: logging.Logger, path="i18n.yaml", fallback_lang="en"): self.logger = logger self._path = path self._fallback_lang = fallback_lang self._dict = dict() self.load() @property def path(self): return self._path @property def fallback_lang(self): return self._fallback_lang def load(self): self._dict.clear() with open(self._path) as f: self._dict = safe_load(f) if self.fallback_lang not in self._dict: raise RuntimeError("I18N file doesn't contain fallback language section") def get(self, phrase: str, lang: Optional[str] = None): lang = lang or self.fallback_lang if lang not in self._dict: self.logger.warning(f"Language '{lang}' not found in i18n, using fallback") lang = self.fallback_lang lang_dict = self._dict.get(lang) result = lang_dict.get(phrase) if result is None: self.logger.error(f"Phrase '{phrase}' not found in language '{lang}'") result = f"" return result def __call__(self, phrase: str, lang: Optional[str] = None, *args, **kwargs): return self.get(phrase, lang).format(*args, **kwargs) def custom_call(self, lang: Optional[str] = None, *args, **kwargs): def call(phrase: str, ilang: Optional[str] = None, *iargs, **ikwargs): return self(phrase, lang or ilang, *args, *iargs, **kwargs, **ikwargs) return call