From cf62badce91079b389af250a14354e5929363a22 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 24 Feb 2018 15:33:11 +0900 Subject: [PATCH] Add namespace feature to sphinx.locale --- sphinx/locale/__init__.py | 31 ++++++++++++++++++------------- tests/test_locale.py | 9 ++++++++- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index f56dd7645..49a88f461 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -200,7 +200,7 @@ def lazy_gettext(string): return _TranslationProxy(mygettext, string) # type: ignore -translators = defaultdict(NullTranslations) # type: Dict[unicode, NullTranslations] +translators = defaultdict(NullTranslations) # type: Dict[Tuple[unicode, unicode], NullTranslations] # NOQA def __(message, *args): @@ -213,7 +213,7 @@ def __(message, *args): return message if len(args) <= 1 else args[0] -def init(locale_dirs, language, catalog='sphinx'): +def init(locale_dirs, language, catalog='sphinx', namespace='general'): # type: (List, unicode, unicode) -> Tuple[Any, bool] """Look for message catalogs in `locale_dirs` and *ensure* that there is at least a NullTranslations catalog set in `translators`. If called multiple @@ -221,7 +221,7 @@ def init(locale_dirs, language, catalog='sphinx'): together (thus making ``init`` reentrable). """ global translators - translator = translators.get(catalog) + translator = translators.get((namespace, catalog)) # ignore previously failed attempts to find message catalogs if isinstance(translator, NullTranslations): translator = None @@ -240,23 +240,28 @@ def init(locale_dirs, language, catalog='sphinx'): except Exception: # Language couldn't be found in the specified path pass - # guarantee translators[catalog] exists + # guarantee translators[(namespace, catalog)] exists if translator is None: translator = NullTranslations() has_translation = False - translators[catalog] = translator + translators[(namespace, catalog)] = translator if hasattr(translator, 'ugettext'): translator.gettext = translator.ugettext return translator, has_translation -def get_translator(catalog='sphinx'): - # type: (unicode) -> NullTranslations - return translators[catalog] +def get_translator(catalog='sphinx', namespace='general'): + # type: (unicode, unicode) -> NullTranslations + return translators[(namespace, catalog)] -def get_translation(catalog): - # type: (unicode) -> Callable[[unicode, *Any], unicode] +def is_translator_registered(catalog='sphinx', namespace='general'): + # type: (unicode, unicode) -> bool + return (namespace, catalog) in translators + + +def get_translation(catalog, namespace='general'): + # type: (unicode, unicode) -> Callable[[unicode, *Any], unicode] """Get a translation function based on the *catalog*, *locale_dir*. The extension can use this API to translate the messages on the @@ -282,16 +287,16 @@ def get_translation(catalog): """ def lazy_gettext(message): # type: (unicode) -> unicode - translator = get_translator(catalog) + translator = get_translator(catalog, namespace) return translator.gettext(message) def gettext(message, *args): # type: (unicode, *Any) -> unicode - if catalog not in translators: + if is_translator_registered(catalog, namespace): # not initialized yet return _TranslationProxy(lazy_gettext, message) else: - translator = get_translator(catalog) + translator = get_translator(catalog, namespace) if len(args) <= 1: return translator.gettext(message) else: # support pluralization diff --git a/tests/test_locale.py b/tests/test_locale.py index 3b3bc67f3..93cb9fcbd 100644 --- a/tests/test_locale.py +++ b/tests/test_locale.py @@ -17,7 +17,7 @@ from sphinx import locale @pytest.fixture(autouse=True) def cleanup_translations(): yield - locale.translators = {} + locale.translators.clear() def test_init(rootdir): @@ -34,6 +34,13 @@ def test_init(rootdir): assert _('Hello sphinx') == 'Hello sphinx' assert _('Hello reST') == 'Hello reST' + # load a catalog to unrelated namespace + locale.init([rootdir / 'test-locale' / 'locale2'], 'en', 'myext', 'mynamespace') + _ = locale.get_translation('myext') + assert _('Hello world') == 'HELLO WORLD' + assert _('Hello sphinx') == 'Hello sphinx' # nothing changed here + assert _('Hello reST') == 'Hello reST' + # load both locale1 and locale2 locale.init([rootdir / 'test-locale' / 'locale1', rootdir / 'test-locale' / 'locale2'], 'en', 'myext')