summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babel/numbers.py52
-rw-r--r--docs/api/numbers.rst2
-rw-r--r--tests/test_numbers.py21
3 files changed, 58 insertions, 17 deletions
diff --git a/babel/numbers.py b/babel/numbers.py
index 9df19e9..cc825c8 100644
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -157,6 +157,36 @@ def get_currency_precision(currency):
return precisions.get(currency, precisions['DEFAULT'])[0]
+def get_currency_unit_pattern(currency, count=None, locale=LC_NUMERIC):
+ """
+ Return the unit pattern used for long display of a currency value
+ for a given locale.
+ This is a string containing ``{0}`` where the numeric part
+ should be substituted and ``{1}`` where the currency long display
+ name should be substituted.
+
+ >>> get_currency_unit_pattern('USD', locale='en_US', count=10)
+ u'{0} {1}'
+
+ .. versionadded:: 2.7.0
+
+ :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.
+ """
+ loc = Locale.parse(locale)
+ if count is not None:
+ plural_form = loc.plural_form(count)
+ try:
+ return loc._data['currency_unit_patterns'][plural_form]
+ except LookupError:
+ # Fall back to 'other'
+ pass
+
+ return loc._data['currency_unit_patterns']['other']
+
+
def get_territory_currencies(territory, start_date=None, end_date=None,
tender=True, non_tender=False,
include_details=False):
@@ -501,28 +531,18 @@ def _format_currency_long_name(
# There are no examples of items with explicit count (0 or 1) in current
# locale data. So there is no point implementing that.
# Step 2.
+
+ # Correct number to numeric type, important for looking up plural rules:
if isinstance(number, string_types):
- plural_category = locale.plural_form(float(number))
+ number_n = float(number)
else:
- plural_category = locale.plural_form(number)
+ number_n = number
# Step 3.
- try:
- unit_pattern = locale._data['currency_unit_patterns'][plural_category]
- except LookupError:
- unit_pattern = locale._data['currency_unit_patterns']['other']
+ unit_pattern = get_currency_unit_pattern(currency, count=number_n, locale=locale)
# Step 4.
- try:
- display_name = locale._data['currency_names_plural'][currency][plural_category]
- except LookupError:
- try:
- display_name = locale._data['currency_names_plural'][currency]['other']
- except LookupError:
- try:
- display_name = locale._data['currency_names'][currency]
- except LookupError:
- display_name = currency
+ display_name = get_currency_name(currency, count=number_n, locale=locale)
# Step 5.
if not format:
diff --git a/docs/api/numbers.rst b/docs/api/numbers.rst
index 1b21425..758ceba 100644
--- a/docs/api/numbers.rst
+++ b/docs/api/numbers.rst
@@ -38,6 +38,8 @@ Data Access
.. autofunction:: get_currency_symbol
+.. autofunction:: get_currency_unit_pattern
+
.. autofunction:: get_decimal_symbol
.. autofunction:: get_plus_sign_symbol
diff --git a/tests/test_numbers.py b/tests/test_numbers.py
index f0239cb..32f4280 100644
--- a/tests/test_numbers.py
+++ b/tests/test_numbers.py
@@ -19,7 +19,7 @@ from datetime import date
from babel import Locale, localedata, numbers
from babel.numbers import (
list_currencies, validate_currency, UnknownCurrencyError, is_currency, normalize_currency,
- get_currency_precision, get_decimal_precision)
+ get_currency_precision, get_decimal_precision, get_currency_unit_pattern)
from babel.localedata import locale_identifiers
from babel._compat import decimal
@@ -228,6 +228,17 @@ def test_get_currency_precision():
assert get_currency_precision('JPY') == 0
+def test_get_currency_unit_pattern():
+ assert get_currency_unit_pattern('USD', locale='en_US') == '{0} {1}'
+ assert get_currency_unit_pattern('USD', locale='es_GT') == '{1} {0}'
+
+ # 'ro' locale various pattern according to count
+ assert get_currency_unit_pattern('USD', locale='ro', count=1) == '{0} {1}'
+ assert get_currency_unit_pattern('USD', locale='ro', count=2) == '{0} {1}'
+ assert get_currency_unit_pattern('USD', locale='ro', count=100) == '{0} de {1}'
+ assert get_currency_unit_pattern('USD', locale='ro') == '{0} de {1}'
+
+
def test_get_territory_currencies():
assert numbers.get_territory_currencies('AT', date(1995, 1, 1)) == ['ATS']
assert numbers.get_territory_currencies('AT', date(2011, 1, 1)) == ['EUR']
@@ -434,6 +445,14 @@ def test_format_currency_long_display_name():
assert (numbers.format_currency(1099.98, 'XAB', locale='en_US', format_type='name')
== u'1,099.98 XAB')
+ # Test for finding different unit patterns depending on count
+ assert (numbers.format_currency(1, 'USD', locale='ro', format_type='name')
+ == u'1,00 dolar american')
+ assert (numbers.format_currency(2, 'USD', locale='ro', format_type='name')
+ == u'2,00 dolari americani')
+ assert (numbers.format_currency(100, 'USD', locale='ro', format_type='name')
+ == u'100,00 de dolari americani')
+
def test_format_currency_long_display_name_all():
for locale_code in localedata.locale_identifiers():