]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
`default_locale`: support multiple keys
authorAarni Koskela <akx@iki.fi>
Tue, 14 Jan 2025 14:32:22 +0000 (16:32 +0200)
committerAarni Koskela <akx@iki.fi>
Wed, 29 Jan 2025 06:53:46 +0000 (08:53 +0200)
Also ignore falsy values in `default_locale` args.

babel/core.py
tests/test_core.py

index 1c7732b5378bd715d73886d77f2ee7638c93acd8..bffef94db670dd931016260addcda1ff9141975d 100644 (file)
@@ -1089,7 +1089,10 @@ class Locale:
         return self._data['unit_display_names']
 
 
-def default_locale(category: str | None = None, aliases: Mapping[str, str] = LOCALE_ALIASES) -> str | None:
+def default_locale(
+    category: str | tuple[str, ...] | list[str] | None = None,
+    aliases: Mapping[str, str] = LOCALE_ALIASES,
+) -> str | None:
     """Returns the system default locale for a given category, based on
     environment variables.
 
@@ -1113,11 +1116,22 @@ def default_locale(category: str | None = None, aliases: Mapping[str, str] = LOC
     - ``LC_CTYPE``
     - ``LANG``
 
-    :param category: one of the ``LC_XXX`` environment variable names
+    :param category: one or more of the ``LC_XXX`` environment variable names
     :param aliases: a dictionary of aliases for locale identifiers
     """
-    varnames = (category, 'LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG')
-    for name in filter(None, varnames):
+
+    varnames = ('LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG')
+    if category:
+        if isinstance(category, str):
+            varnames = (category, *varnames)
+        elif isinstance(category, (list, tuple)):
+            varnames = (*category, *varnames)
+        else:
+            raise TypeError(f"Invalid type for category: {category!r}")
+
+    for name in varnames:
+        if not name:
+            continue
         locale = os.getenv(name)
         if locale:
             if name == 'LANGUAGE' and ':' in locale:
index b6c55626cfc1509ee22e2471facf34a5635987c0..8770cf8d9cd4b2c90f8734c13d6da388c73020e4 100644 (file)
@@ -265,7 +265,7 @@ class TestLocaleClass:
 
 
 def test_default_locale(monkeypatch):
-    for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
+    for name in ['LANGUAGE', 'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
         monkeypatch.setenv(name, '')
     monkeypatch.setenv('LANG', 'fr_FR.UTF-8')
     assert default_locale('LC_MESSAGES') == 'fr_FR'
@@ -277,6 +277,23 @@ def test_default_locale(monkeypatch):
         assert default_locale() == 'en_US_POSIX'
 
 
+def test_default_locale_multiple_args(monkeypatch):
+    for name in ['LANGUAGE', 'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', 'LC_MONETARY', 'LC_NUMERIC']:
+        monkeypatch.setenv(name, '')
+    assert default_locale(["", 0, None]) is None
+    monkeypatch.setenv('LANG', 'en_US')
+    assert default_locale(('LC_MONETARY', 'LC_NUMERIC')) == 'en_US'  # No LC_MONETARY or LC_NUMERIC set
+    monkeypatch.setenv('LC_NUMERIC', 'fr_FR.UTF-8')
+    assert default_locale(('LC_MONETARY', 'LC_NUMERIC')) == 'fr_FR'  # LC_NUMERIC set
+    monkeypatch.setenv('LC_MONETARY', 'fi_FI.UTF-8')
+    assert default_locale(('LC_MONETARY', 'LC_NUMERIC')) == 'fi_FI'  # LC_MONETARY set, it takes precedence
+
+
+def test_default_locale_bad_arg():
+    with pytest.raises(TypeError):
+        default_locale(42)
+
+
 def test_negotiate_locale():
     assert (core.negotiate_locale(['de_DE', 'en_US'], ['de_DE', 'de_AT']) ==
             'de_DE')