Source code for aiogram_i18n.cores.gnu_text_core

from gettext import GNUTranslations
from pathlib import Path
from typing import Any, NoReturn

from aiogram_i18n.cores.base import BaseCore
from aiogram_i18n.exceptions import KeyNotFoundError, UnknownLocaleError


class Fallback:
    def gettext(self, message: str) -> NoReturn:  # noqa: ARG002
        raise KeyError

    def ngettext(self, msgid1: str, msgid2: str | None, n: int) -> NoReturn:  # noqa: ARG002
        raise KeyError


[docs] class GNUTextCore(BaseCore[GNUTranslations]): def __init__( self, *, path: str | Path, default_locale: str | None = None, raise_key_error: bool = False, locales_map: dict[str, str] | None = None, ) -> None: super().__init__(path=path, default_locale=default_locale, locales_map=locales_map) self.raise_key_error = raise_key_error
[docs] def find_locales(self) -> dict[str, GNUTranslations]: """ Load all compiled locales from path :return: dict with locales """ fallback = Fallback() translations: dict[str, GNUTranslations] = {} locales = self._extract_locales(self.path) for locale, paths in self._find_locales(self.path, locales, ".mo").items(): trans = translations[locale] = GNUTranslations() trans._fallback = fallback # type: ignore[attr-defined] # noqa: SLF001 for path in paths: with path.open("rb") as fp: trans._parse(fp=fp) # noqa: SLF001 for locale, fallback_locale in self.locales_map.items(): if locale not in translations: raise UnknownLocaleError(locale) if fallback_locale not in translations: raise UnknownLocaleError(fallback_locale) translations[locale]._fallback = translations[ # type: ignore[attr-defined] # noqa: SLF001 fallback_locale ] return translations
[docs] def get(self, message: str, locale: str | None = None, /, **kwargs: Any) -> str: locale = self.get_locale(locale=locale) translator = self.get_translator(locale=locale) try: return translator.gettext(message=message).format_map(kwargs) except KeyError: if self.raise_key_error: raise KeyNotFoundError(message) from None return message.format_map(kwargs)
[docs] def nget( self, singular: str, plural: str | None = None, n: int = 1, locale: str | None = None, /, **kwargs: Any, ) -> str: locale = self.get_locale(locale=locale) translator = self.get_translator(locale=locale) if plural is None: plural = singular try: return translator.ngettext(msgid1=singular, msgid2=plural, n=n).format_map(kwargs) except KeyError: if self.raise_key_error: raise KeyNotFoundError(singular) from None if n == 1: return singular return plural