Add namespace feature to sphinx.locale

This commit is contained in:
Takeshi KOMIYA 2018-02-24 15:33:11 +09:00
parent 747a161cab
commit cf62badce9
2 changed files with 26 additions and 14 deletions

View File

@ -200,7 +200,7 @@ def lazy_gettext(string):
return _TranslationProxy(mygettext, string) # type: ignore 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): def __(message, *args):
@ -213,7 +213,7 @@ def __(message, *args):
return message if len(args) <= 1 else args[0] 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] # type: (List, unicode, unicode) -> Tuple[Any, bool]
"""Look for message catalogs in `locale_dirs` and *ensure* that there is at """Look for message catalogs in `locale_dirs` and *ensure* that there is at
least a NullTranslations catalog set in `translators`. If called multiple 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). together (thus making ``init`` reentrable).
""" """
global translators global translators
translator = translators.get(catalog) translator = translators.get((namespace, catalog))
# ignore previously failed attempts to find message catalogs # ignore previously failed attempts to find message catalogs
if isinstance(translator, NullTranslations): if isinstance(translator, NullTranslations):
translator = None translator = None
@ -240,23 +240,28 @@ def init(locale_dirs, language, catalog='sphinx'):
except Exception: except Exception:
# Language couldn't be found in the specified path # Language couldn't be found in the specified path
pass pass
# guarantee translators[catalog] exists # guarantee translators[(namespace, catalog)] exists
if translator is None: if translator is None:
translator = NullTranslations() translator = NullTranslations()
has_translation = False has_translation = False
translators[catalog] = translator translators[(namespace, catalog)] = translator
if hasattr(translator, 'ugettext'): if hasattr(translator, 'ugettext'):
translator.gettext = translator.ugettext translator.gettext = translator.ugettext
return translator, has_translation return translator, has_translation
def get_translator(catalog='sphinx'): def get_translator(catalog='sphinx', namespace='general'):
# type: (unicode) -> NullTranslations # type: (unicode, unicode) -> NullTranslations
return translators[catalog] return translators[(namespace, catalog)]
def get_translation(catalog): def is_translator_registered(catalog='sphinx', namespace='general'):
# type: (unicode) -> Callable[[unicode, *Any], unicode] # 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*. """Get a translation function based on the *catalog*, *locale_dir*.
The extension can use this API to translate the messages on the The extension can use this API to translate the messages on the
@ -282,16 +287,16 @@ def get_translation(catalog):
""" """
def lazy_gettext(message): def lazy_gettext(message):
# type: (unicode) -> unicode # type: (unicode) -> unicode
translator = get_translator(catalog) translator = get_translator(catalog, namespace)
return translator.gettext(message) return translator.gettext(message)
def gettext(message, *args): def gettext(message, *args):
# type: (unicode, *Any) -> unicode # type: (unicode, *Any) -> unicode
if catalog not in translators: if is_translator_registered(catalog, namespace):
# not initialized yet # not initialized yet
return _TranslationProxy(lazy_gettext, message) return _TranslationProxy(lazy_gettext, message)
else: else:
translator = get_translator(catalog) translator = get_translator(catalog, namespace)
if len(args) <= 1: if len(args) <= 1:
return translator.gettext(message) return translator.gettext(message)
else: # support pluralization else: # support pluralization

View File

@ -17,7 +17,7 @@ from sphinx import locale
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def cleanup_translations(): def cleanup_translations():
yield yield
locale.translators = {} locale.translators.clear()
def test_init(rootdir): def test_init(rootdir):
@ -34,6 +34,13 @@ def test_init(rootdir):
assert _('Hello sphinx') == 'Hello sphinx' assert _('Hello sphinx') == 'Hello sphinx'
assert _('Hello reST') == 'Hello reST' 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 # load both locale1 and locale2
locale.init([rootdir / 'test-locale' / 'locale1', locale.init([rootdir / 'test-locale' / 'locale1',
rootdir / 'test-locale' / 'locale2'], 'en', 'myext') rootdir / 'test-locale' / 'locale2'], 'en', 'myext')