Skip to content

Commit

Permalink
Revert "Refactor _TranslationProxy"
Browse files Browse the repository at this point in the history
This reverts commit 2c83af0.
  • Loading branch information
jayaddison committed Apr 11, 2023
1 parent 14f2969 commit 5d67627
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions sphinx/locale/__init__.py
Expand Up @@ -10,44 +10,50 @@

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__ = '_catalogue', '_namespace', '_message'
__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

def __init__(self, catalogue: str, namespace: str, message: str) -> None:
self._catalogue = catalogue
self._namespace = namespace
self._message = message
def __init__(self, func: Callable[..., str], *args: str) -> None:
self._func = func
self._args = args

def __str__(self) -> str:
try:
return translators[self._namespace, self._catalogue].gettext(self._message)
except KeyError:
# NullTranslations().gettext(self._message) == self._message
return self._message
return str(self._func(*self._args))

def __dir__(self) -> list[str]:
return dir(str)

def __getattr__(self, name: str) -> Any:
return getattr(self.__str__(), name)

def __getstate__(self) -> tuple[str, str, str]:
return self._catalogue, self._namespace, self._message
def __getstate__(self) -> tuple[Callable[..., str], tuple[str, ...]]:
return self._func, self._args

def __setstate__(self, tup: tuple[str, str, str]) -> None:
self._catalogue, self._namespace, self._message = tup
def __setstate__(self, tup: tuple[Callable[..., str], tuple[str]]) -> None:
self._func, self._args = tup

def __copy__(self) -> _TranslationProxy:
return _TranslationProxy(self._catalogue, self._namespace, self._message)
return _TranslationProxy(self._func, *self._args)

def __repr__(self) -> str:
try:
return f'i{self.__str__()!r}'
return 'i' + repr(str(self.__str__()))
except Exception:
return (self.__class__.__name__
+ f'({self._catalogue}, {self._namespace}, {self._message})')
return f'<{self.__class__.__name__} broken>'

def __add__(self, other: str) -> str:
return self.__str__() + other
Expand Down Expand Up @@ -104,6 +110,8 @@ 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
Expand All @@ -117,17 +125,15 @@ 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:
if '_' in language:
# for language having country code (like "de_AT")
languages = [language, language.split('_')[0]]
else:
languages = [language]
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)
Expand All @@ -138,13 +144,11 @@ def init(
except Exception:
# Language couldn't be found in the specified path
pass
if translator is not None:
has_translation = True
else:
# guarantee translators[(namespace, catalog)] exists
if translator is None:
translator = NullTranslations()
has_translation = False
# guarantee translators[(namespace, catalog)] exists
translators[namespace, catalog] = translator
translators[(namespace, catalog)] = translator
return translator, has_translation


Expand Down Expand Up @@ -177,6 +181,14 @@ 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*.
Expand All @@ -202,8 +214,8 @@ def setup(app):
.. versionadded:: 1.8
"""
def gettext(message: str) -> str:
return _TranslationProxy(catalog, namespace, message) # type: ignore[return-value]
def gettext(message: str, *args: Any) -> str:
return _TranslationProxy(_lazy_translate, catalog, namespace, message, *args) # type: ignore[return-value] # NOQA

return gettext

Expand Down

0 comments on commit 5d67627

Please sign in to comment.