summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonah Lawrence <jonah@freshidea.com>2023-01-06 13:21:58 -0700
committerGitHub <noreply@github.com>2023-01-06 22:21:58 +0200
commit3594836cd9e64b6c98f008ee7e25614de7d9db68 (patch)
tree852b288bdccb8b2091139cc067c12457ebaf1789
parentd425f86a08d5f459d7380d7c196ecb33af564f5c (diff)
downloadbabel-3594836cd9e64b6c98f008ee7e25614de7d9db68.tar.gz
Fix compact singular formats and patterns with no numbers (#932)
-rw-r--r--babel/numbers.py19
-rw-r--r--tests/test_numbers.py7
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):