This commit is contained in:
Stan Ulbrych 2025-06-19 15:20:29 +01:00
parent c85d0c26ad
commit c40039fa3d
No known key found for this signature in database
GPG key ID: B8E58DBDB2A1A0B8
3 changed files with 50 additions and 17 deletions

View file

@ -131,8 +131,8 @@ install themselves in the built-in namespace as the function :func:`!_`.
If *localedir* is not given, then the default system locale directory is used. If *localedir* is not given, then the default system locale directory is used.
[#]_ If *languages* is not given, then the environment variable :envvar:`LANGUAGE` [#]_ If *languages* is not given, then the environment variable :envvar:`LANGUAGE`
is searched, it falls back to :func:`locale.setlocale`, which in turn falls is searched, it falls back to the current locale or to the environment
back to the environment variables :envvar:`LC_ALL`, :envvar:`LC_MESSAGES`, and variables :envvar:`LC_ALL`, :envvar:`LC_MESSAGES`, and
:envvar:`LANG` where the first one returning a non-empty value is used for the :envvar:`LANG` where the first one returning a non-empty value is used for the
*languages* variable. The environment variables should contain a colon separated *languages* variable. The environment variables should contain a colon separated
list of languages, which will be split on the colon to produce the expected list list of languages, which will be split on the colon to produce the expected list

View file

@ -493,8 +493,8 @@ def find(domain, localedir=None, languages=None, all=False):
languages = [] languages = []
if val := os.environ.get('LANGUAGE'): if val := os.environ.get('LANGUAGE'):
languages = val.split(':') languages = val.split(':')
elif (loc := locale.setlocale(locale.LC_MESSAGES)) != (None, None): elif loc := locale.setlocale(locale.LC_MESSAGES):
languages = [".".join(filter(None, loc))] languages = loc.split(':')
else: else:
for envar in ('LC_ALL', 'LC_MESSAGES', 'LANG'): for envar in ('LC_ALL', 'LC_MESSAGES', 'LANG'):
val = os.environ.get(envar) val = os.environ.get(envar)

View file

@ -1,3 +1,6 @@
import sys
import locale
import os import os
import base64 import base64
import gettext import gettext
@ -6,8 +9,7 @@
from functools import partial from functools import partial
from test import support from test import support
from test.support import os_helper from test.support import os_helper, run_with_locale
# TODO: # TODO:
# - Add new tests, for example for "dgettext" # - Add new tests, for example for "dgettext"
@ -736,32 +738,63 @@ def create_mo_file(self, lang):
f.write(GNU_MO_DATA) f.write(GNU_MO_DATA)
return mo_file return mo_file
def _for_all_vars(self, mo_file, locale): def _for_all_vars(self, mo_file, locale, expected=True):
for var in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): for var in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
self.env.set(var, locale) self.env.set(var, locale)
result = gettext.find("mofile", result = gettext.find("mofile",
localedir=os.path.join(self.tempdir, "locale")) localedir=os.path.join(self.tempdir, "locale"))
self.assertEqual(mo_file, result) if expected:
self.assertEqual(mo_file, result)
else:
self.assertIsNone(result)
self.env.unset(var) self.env.unset(var)
@unittest.mock.patch("locale.setlocale", return_value=(None, None)) @unittest.mock.patch("locale.setlocale", return_value='')
def test_find_with_env_vars(self, patch_getlocale): def test_find_with_env_vars(self, patch_getlocale):
# test that find correctly finds the environment variables # test that find correctly finds the environment variables
# when languages are not supplied # when languages are not supplied
mo_file = self.create_mo_file("ca_ES")
self._for_all_vars(mo_file, "ca_ES")
self._for_all_vars(mo_file, "ca_ES.UTF-8")
self._for_all_vars(mo_file, "ca_ES.UTF-8.mo")
self._for_all_vars(mo_file, "es_ES:ca_ES:fr_FR")
self._for_all_vars(mo_file, "ca_ES@euro")
self._for_all_vars(mo_file, "ca_ES.UTF-8@euro")
self._for_all_vars(mo_file, "ca_ES@valencia")
self._for_all_vars(mo_file, "C", expected=False)
self._for_all_vars(mo_file, "C.UTF-8", expected=False)
@unittest.mock.patch('gettext._expand_lang')
def test_encoding_not_ignored(self, patch_expand_lang):
self.env.set('LANGUAGE', 'ga_IE.UTF-8')
gettext.find("mofile")
patch_expand_lang.assert_any_call('ga_IE.UTF-8')
self.env.unset('LANGUAGE')
def test_find_LANGUAGE_priority(self):
orig = locale.setlocale(locale.LC_MESSAGES)
self.addCleanup(lambda: locale.setlocale(locale.LC_MESSAGES, orig))
self.env.set('LANGUAGE', 'ga_IE')
self.env.set('LC_ALL', 'pt_BR')
locale.setlocale(locale.LC_MESSAGES, 'pt_BR')
mo_file = self.create_mo_file("ga_IE") mo_file = self.create_mo_file("ga_IE")
self._for_all_vars(mo_file, "ga_IE")
self._for_all_vars(mo_file, "ga_IE.UTF-8") result = gettext.find("mofile", localedir=os.path.join(self.tempdir, "locale"))
self._for_all_vars(mo_file, "es_ES:ga_IE:fr_FR") self.assertEqual(result, mo_file)
self._for_all_vars(mo_file, "ga_IE@euro") locale.setlocale(locale.LC_MESSAGES, orig)
def test_process_vars_override(self): def test_process_vars_override(self):
mo_file = self.create_mo_file("ga_IE") orig = locale.setlocale(locale.LC_MESSAGES)
with unittest.mock.patch("locale.setlocale", return_value=('ga_IE', 'UTF-8')): self.addCleanup(lambda: locale.setlocale(locale.LC_MESSAGES, orig))
mo_file = self.create_mo_file("ca_ES")
for loc in ("ca_ES", "ca_ES.UTF-8", "ca_ES@euro", "ca_ES@valencia"):
locale.setlocale(locale.LC_MESSAGES, loc)
result = gettext.find("mofile", localedir=os.path.join(self.tempdir, "locale")) result = gettext.find("mofile", localedir=os.path.join(self.tempdir, "locale"))
self.assertEqual(mo_file, result) self.assertEqual(mo_file, result)
with unittest.mock.patch("locale.setlocale", return_value=('ga_IE', None)): for loc in ("C", "C.UTF-8"):
locale.setlocale(locale.LC_MESSAGES, loc)
result = gettext.find("mofile", localedir=os.path.join(self.tempdir, "locale")) result = gettext.find("mofile", localedir=os.path.join(self.tempdir, "locale"))
self.assertEqual(mo_file, result) self.assertIsNone(result)
def test_find_with_languages(self): def test_find_with_languages(self):
# test that passed languages are used # test that passed languages are used