]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Prefer LC_MONETARY when formatting currency lc-monetary-2 1173/head
authorAarni Koskela <akx@iki.fi>
Thu, 21 Dec 2023 23:42:55 +0000 (00:42 +0100)
committerAarni Koskela <akx@iki.fi>
Wed, 29 Jan 2025 06:53:50 +0000 (08:53 +0200)
Co-authored-by: Alexis Hildebrandt <afh@surryhill.net>
babel/numbers.py
tests/test_numbers.py

index a2b89cc315386cebfe0bee2d1a1c74a6f2a7a823..8dd4d9eaeecc5a23a53e849b8a6119debd902144 100644 (file)
@@ -7,7 +7,8 @@
     The default locale for the functions in this module is determined by the
     following environment variables, in that order:
 
-     * ``LC_NUMERIC``,
+     * ``LC_MONETARY`` for currency related functions,
+     * ``LC_NUMERIC``, and
      * ``LC_ALL``, and
      * ``LANG``
 
@@ -28,6 +29,7 @@ from typing import Any, Literal, cast, overload
 from babel.core import Locale, default_locale, get_global
 from babel.localedata import LocaleDataDict
 
+LC_MONETARY = default_locale(('LC_MONETARY', 'LC_NUMERIC'))
 LC_NUMERIC = default_locale('LC_NUMERIC')
 
 
@@ -117,9 +119,10 @@ def get_currency_name(
     :param currency: the currency code.
     :param count: the optional count.  If provided the currency name
                   will be pluralized to that number if possible.
-    :param locale: the `Locale` object or locale identifier. Defaults to the system numeric locale.
+    :param locale: the `Locale` object or locale identifier.
+                   Defaults to the system currency locale or numeric locale.
     """
-    loc = Locale.parse(locale or LC_NUMERIC)
+    loc = Locale.parse(locale or LC_MONETARY)
     if count is not None:
         try:
             plural_form = loc.plural_form(count)
@@ -142,9 +145,10 @@ def get_currency_symbol(currency: str, locale: Locale | str | None = None) -> st
     u'$'
 
     :param currency: the currency code.
-    :param locale: the `Locale` object or locale identifier. Defaults to the system numeric locale.
+    :param locale: the `Locale` object or locale identifier.
+                   Defaults to the system currency locale or numeric locale.
     """
-    return Locale.parse(locale or LC_NUMERIC).currency_symbols.get(currency, currency)
+    return Locale.parse(locale or LC_MONETARY).currency_symbols.get(currency, currency)
 
 
 def get_currency_precision(currency: str) -> int:
@@ -181,9 +185,10 @@ def get_currency_unit_pattern(
     :param currency: the currency code.
     :param count: the optional count.  If provided the unit
                   pattern for that number will be returned.
-    :param locale: the `Locale` object or locale identifier. Defaults to the system numeric locale.
+    :param locale: the `Locale` object or locale identifier.
+                   Defaults to the system currency locale or numeric locale.
     """
-    loc = Locale.parse(locale or LC_NUMERIC)
+    loc = Locale.parse(locale or LC_MONETARY)
     if count is not None:
         plural_form = loc.plural_form(count)
         try:
@@ -760,7 +765,8 @@ def format_currency(
     :param number: the number to format
     :param currency: the currency code
     :param format: the format string to use
-    :param locale: the `Locale` object or locale identifier. Defaults to the system numeric locale.
+    :param locale: the `Locale` object or locale identifier.
+                   Defaults to the system currency locale or numeric locale.
     :param currency_digits: use the currency's natural number of decimal digits
     :param format_type: the currency format type to use
     :param decimal_quantization: Truncate and round high-precision numbers to
@@ -771,7 +777,7 @@ def format_currency(
                              The special value "default" will use the default numbering system of the locale.
     :raise `UnsupportedNumberingSystemError`: If the numbering system is not supported by the locale.
     """
-    locale = Locale.parse(locale or LC_NUMERIC)
+    locale = Locale.parse(locale or LC_MONETARY)
 
     if format_type == 'name':
         return _format_currency_long_name(
@@ -860,13 +866,14 @@ def format_compact_currency(
     :param number: the number to format
     :param currency: the currency code
     :param format_type: the compact format type to use. Defaults to "short".
-    :param locale: the `Locale` object or locale identifier. Defaults to the system numeric locale.
+    :param locale: the `Locale` object or locale identifier.
+                   Defaults to the system currency locale or numeric locale.
     :param fraction_digits: Number of digits after the decimal point to use. Defaults to `0`.
     :param numbering_system: The numbering system used for formatting number symbols. Defaults to "latn".
                              The special value "default" will use the default numbering system of the locale.
     :raise `UnsupportedNumberingSystemError`: If the numbering system is not supported by the locale.
     """
-    locale = Locale.parse(locale or LC_NUMERIC)
+    locale = Locale.parse(locale or LC_MONETARY)
     try:
         compact_format = locale.compact_currency_formats[format_type]
     except KeyError as error:
index cf0e8d1ba6cb1a2249f005056b42f6444d560e31..45892fe2cdcc9545760fb7058d2ee647029d61cd 100644 (file)
@@ -485,19 +485,6 @@ def test_format_currency():
             == 'US$0,00')          # other
 
 
-def test_format_currency_with_none_locale_with_default(monkeypatch):
-    """Test that the default locale is used when locale is None."""
-    monkeypatch.setattr(numbers, "LC_NUMERIC", "fi_FI")
-    assert numbers.format_currency(0, "USD", locale=None) == "0,00\xa0$"
-
-
-def test_format_currency_with_none_locale(monkeypatch):
-    """Test that the API raises the "Empty locale identifier" error when locale is None, and the default is too."""
-    monkeypatch.setattr(numbers, "LC_NUMERIC", None)  # Pretend we couldn't find any locale when importing the module
-    with pytest.raises(TypeError, match="Empty"):
-        numbers.format_currency(0, "USD", locale=None)
-
-
 def test_format_currency_format_type():
     assert (numbers.format_currency(1099.98, 'USD', locale='en_US',
                                     format_type="standard")
@@ -867,3 +854,31 @@ def test_single_quotes_in_pattern():
     assert numbers.format_decimal(123, "'$'''0", locale='en') == "$'123"
 
     assert numbers.format_decimal(12, "'#'0 o''clock", locale='en') == "#12 o'clock"
+
+
+def test_format_currency_with_none_locale_with_default(monkeypatch):
+    """Test that the default locale is used when locale is None."""
+    monkeypatch.setattr(numbers, "LC_MONETARY", "fi_FI")
+    monkeypatch.setattr(numbers, "LC_NUMERIC", None)
+    assert numbers.format_currency(0, "USD", locale=None) == "0,00\xa0$"
+
+
+def test_format_currency_with_none_locale(monkeypatch):
+    """Test that the API raises the "Empty locale identifier" error when locale is None, and the default is too."""
+    monkeypatch.setattr(numbers, "LC_MONETARY", None)  # Pretend we couldn't find any locale when importing the module
+    with pytest.raises(TypeError, match="Empty"):
+        numbers.format_currency(0, "USD", locale=None)
+
+
+def test_format_decimal_with_none_locale_with_default(monkeypatch):
+    """Test that the default locale is used when locale is None."""
+    monkeypatch.setattr(numbers, "LC_NUMERIC", "fi_FI")
+    monkeypatch.setattr(numbers, "LC_MONETARY", None)
+    assert numbers.format_decimal("1.23", locale=None) == "1,23"
+
+
+def test_format_decimal_with_none_locale(monkeypatch):
+    """Test that the API raises the "Empty locale identifier" error when locale is None, and the default is too."""
+    monkeypatch.setattr(numbers, "LC_NUMERIC", None)  # Pretend we couldn't find any locale when importing the module
+    with pytest.raises(TypeError, match="Empty"):
+        numbers.format_decimal(0, locale=None)