summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Turner <9087854+aa-turner@users.noreply.github.com>2023-04-08 05:07:03 +0100
committerAdam Turner <9087854+aa-turner@users.noreply.github.com>2023-04-08 05:09:12 +0100
commit2c83af0aab7080e0b78d4a16981eed878b2cac4c (patch)
treefba5bf497761988125d930a7f86ac5bba90950e6
parent31ca9627136b7660f96fddce25e0f6f8e839fcae (diff)
downloadsphinx-git-2c83af0aab7080e0b78d4a16981eed878b2cac4c.tar.gz
Refactor ``_TranslationProxy``
-rw-r--r--sphinx/locale/__init__.py74
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