diff options
-rw-r--r-- | babel/numbers.py | 52 | ||||
-rw-r--r-- | docs/api/numbers.rst | 2 | ||||
-rw-r--r-- | tests/test_numbers.py | 21 |
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(): |