diff options
author | Adam Turner <9087854+aa-turner@users.noreply.github.com> | 2023-04-08 05:07:03 +0100 |
---|---|---|
committer | Adam Turner <9087854+aa-turner@users.noreply.github.com> | 2023-04-08 05:09:12 +0100 |
commit | 2c83af0aab7080e0b78d4a16981eed878b2cac4c (patch) | |
tree | fba5bf497761988125d930a7f86ac5bba90950e6 | |
parent | 31ca9627136b7660f96fddce25e0f6f8e839fcae (diff) | |
download | sphinx-git-2c83af0aab7080e0b78d4a16981eed878b2cac4c.tar.gz |
Refactor ``_TranslationProxy``
-rw-r--r-- | sphinx/locale/__init__.py | 74 |
1 files changed, 31 insertions, 43 deletions
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 2291fc00b..8bc7a2673 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -10,29 +10,22 @@ from typing import Any, Callable class _TranslationProxy: """ - Class for proxy strings from gettext translations. This is a helper for the - lazy_* functions from this module. - The proxy implementation attempts to be as complete as possible, so that the lazy objects should mostly work as expected, for example for sorting. """ - __slots__ = ('_func', '_args') - - def __new__(cls, func: Callable[..., str], *args: str) -> _TranslationProxy: - if not args: - # not called with "function" and "arguments", but a plain string - return str(func) # type: ignore[return-value] - return object.__new__(cls) - - def __getnewargs__(self) -> tuple[str]: - return (self._func,) + self._args # type: ignore + __slots__ = '_catalogue', '_namespace', '_message' - def __init__(self, func: Callable[..., str], *args: str) -> None: - self._func = func - self._args = args + def __init__(self, catalogue: str, namespace: str, message: str) -> None: + self._catalogue = catalogue + self._namespace = namespace + self._message = message def __str__(self) -> str: - return str(self._func(*self._args)) + try: + return translators[self._namespace, self._catalogue].gettext(self._message) + except KeyError: + # NullTranslations().gettext(self._message) == self._message + return self._message def __dir__(self) -> list[str]: return dir(str) @@ -40,20 +33,21 @@ class _TranslationProxy: def __getattr__(self, name: str) -> Any: return getattr(self.__str__(), name) - def __getstate__(self) -> tuple[Callable[..., str], tuple[str, ...]]: - return self._func, self._args + def __getstate__(self) -> tuple[str, str, str]: + return self._catalogue, self._namespace, self._message - def __setstate__(self, tup: tuple[Callable[..., str], tuple[str]]) -> None: - self._func, self._args = tup + def __setstate__(self, tup: tuple[str, str, str]) -> None: + self._catalogue, self._namespace, self._message = tup def __copy__(self) -> _TranslationProxy: - return _TranslationProxy(self._func, *self._args) + return _TranslationProxy(self._catalogue, self._namespace, self._message) def __repr__(self) -> str: try: - return 'i' + repr(str(self.__str__())) + return f'i{self.__str__()!r}' except Exception: - return f'<{self.__class__.__name__} broken>' + return (self.__class__.__name__ + + f'({self._catalogue}, {self._namespace}, {self._message})') def __add__(self, other: str) -> str: return self.__str__() + other @@ -110,8 +104,6 @@ def init( # ignore previously failed attempts to find message catalogs if translator.__class__ is NullTranslations: translator = None - # the None entry is the system's default locale path - has_translation = True if getenv('SOURCE_DATE_EPOCH') is not None: # Disable localization during reproducible source builds @@ -125,15 +117,17 @@ def init( # To achieve that, specify the ISO-639-3 'undetermined' language code, # which should not match any translation catalogs. languages: list[str] | None = ['und'] - elif language and '_' in language: - # for language having country code (like "de_AT") - languages = [language, language.split('_')[0]] elif language: - languages = [language] + if '_' in language: + # for language having country code (like "de_AT") + languages = [language, language.split('_')[0]] + else: + languages = [language] else: languages = None # loading + # the None entry is the system's default locale path for dir_ in locale_dirs: try: trans = translation(catalog, localedir=dir_, languages=languages) @@ -144,11 +138,13 @@ def init( except Exception: # Language couldn't be found in the specified path pass - # guarantee translators[(namespace, catalog)] exists - if translator is None: + if translator is not None: + has_translation = True + else: translator = NullTranslations() has_translation = False - translators[(namespace, catalog)] = translator + # guarantee translators[(namespace, catalog)] exists + translators[namespace, catalog] = translator return translator, has_translation @@ -181,14 +177,6 @@ def is_translator_registered(catalog: str = 'sphinx', namespace: str = 'general' return (namespace, catalog) in translators -def _lazy_translate(catalog: str, namespace: str, message: str, *args: Any) -> str: - """Used instead of _ when creating TranslationProxy, because _ is - not bound yet at that time. - """ - translator = get_translator(catalog, namespace) - return translator.gettext(message) - - def get_translation(catalog: str, namespace: str = 'general') -> Callable[[str], str]: """Get a translation function based on the *catalog* and *namespace*. @@ -214,8 +202,8 @@ def get_translation(catalog: str, namespace: str = 'general') -> Callable[[str], .. versionadded:: 1.8 """ - def gettext(message: str, *args: Any) -> str: - return _TranslationProxy(_lazy_translate, catalog, namespace, message, *args) # type: ignore[return-value] # NOQA + def gettext(message: str) -> str: + return _TranslationProxy(catalog, namespace, message) # type: ignore[return-value] return gettext |