diff options
author | Jonah Lawrence <jonah@freshidea.com> | 2023-01-06 13:21:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-06 22:21:58 +0200 |
commit | 3594836cd9e64b6c98f008ee7e25614de7d9db68 (patch) | |
tree | 852b288bdccb8b2091139cc067c12457ebaf1789 | |
parent | d425f86a08d5f459d7380d7c196ecb33af564f5c (diff) | |
download | babel-3594836cd9e64b6c98f008ee7e25614de7d9db68.tar.gz |
Fix compact singular formats and patterns with no numbers (#932)
-rw-r--r-- | babel/numbers.py | 19 | ||||
-rw-r--r-- | tests/test_numbers.py | 7 |
2 files changed, 19 insertions, 7 deletions
diff --git a/babel/numbers.py b/babel/numbers.py index 2221e95..da5936d 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -17,6 +17,7 @@ # TODO: # Padding and rounding increments in pattern: # - https://www.unicode.org/reports/tr35/ (Appendix G.6) +from __future__ import annotations import decimal import re from datetime import date as date_, datetime as datetime_ @@ -431,7 +432,7 @@ def format_compact_decimal(number, *, format_type="short", locale=LC_NUMERIC, fr u'123万' >>> format_compact_decimal(2345678, format_type="long", locale="mk") u'2 милиони' - >>> format_compact_decimal(21098765, format_type="long", locale="mk") + >>> format_compact_decimal(21000000, format_type="long", locale="mk") u'21 милион' :param number: the number to format @@ -469,11 +470,15 @@ def _get_compact_format(number, compact_format, locale, fraction_digits=0): # equal to the number of 0's in the pattern minus 1 number = number / (magnitude // (10 ** (pattern.count("0") - 1))) # round to the number of fraction digits requested - number = round(number, fraction_digits) + rounded = round(number, fraction_digits) # if the remaining number is singular, use the singular format plural_form = locale.plural_form(abs(number)) - plural_form = plural_form if plural_form in compact_format else "other" + if plural_form not in compact_format: + plural_form = "other" + if number == 1 and "1" in compact_format: + plural_form = "1" format = compact_format[plural_form][str(magnitude)] + number = rounded break return number, format @@ -960,17 +965,19 @@ def parse_pattern(pattern): return NumberPattern(pattern, (pos_prefix, neg_prefix), (pos_suffix, neg_suffix), grouping, int_prec, frac_prec, - exp_prec, exp_plus) + exp_prec, exp_plus, number) class NumberPattern: def __init__(self, pattern, prefix, suffix, grouping, - int_prec, frac_prec, exp_prec, exp_plus): + int_prec, frac_prec, exp_prec, exp_plus, + number_pattern: str | None = None): # Metadata of the decomposed parsed pattern. self.pattern = pattern self.prefix = prefix self.suffix = suffix + self.number_pattern = number_pattern self.grouping = grouping self.int_prec = int_prec self.frac_prec = frac_prec @@ -1115,7 +1122,7 @@ class NumberPattern: retval = ''.join([ self.prefix[is_negative], - number, + number if self.number_pattern != '' else '', self.suffix[is_negative]]) if u'¤' in retval: diff --git a/tests/test_numbers.py b/tests/test_numbers.py index bb6c4e8..37d2f9e 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -153,7 +153,12 @@ class FormatDecimalTestCase(unittest.TestCase): assert numbers.format_compact_decimal(-123456789, format_type='short', locale='en_US') == u'-123M' assert numbers.format_compact_decimal(-123456789, format_type='long', locale='en_US') == u'-123 million' assert numbers.format_compact_decimal(2345678, locale='mk', format_type='long') == u'2 милиони' - assert numbers.format_compact_decimal(21098765, locale='mk', format_type='long') == u'21 милион' + assert numbers.format_compact_decimal(21000000, locale='mk', format_type='long') == u'21 милион' + assert numbers.format_compact_decimal(21345, locale="gv", format_type="short") == u'21K' + assert numbers.format_compact_decimal(1000, locale='it', format_type='long') == u'mille' + assert numbers.format_compact_decimal(1234, locale='it', format_type='long') == u'1 mila' + assert numbers.format_compact_decimal(1000, locale='fr', format_type='long') == u'mille' + assert numbers.format_compact_decimal(1234, locale='fr', format_type='long') == u'1 millier' class NumberParsingTestCase(unittest.TestCase): |