Skip to content

Commit 3594836

Browse files
authored
Fix compact singular formats and patterns with no numbers (#932)
1 parent d425f86 commit 3594836

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

babel/numbers.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# TODO:
1818
# Padding and rounding increments in pattern:
1919
# - https://www.unicode.org/reports/tr35/ (Appendix G.6)
20+
from __future__ import annotations
2021
import decimal
2122
import re
2223
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
431432
u'123万'
432433
>>> format_compact_decimal(2345678, format_type="long", locale="mk")
433434
u'2 милиони'
434-
>>> format_compact_decimal(21098765, format_type="long", locale="mk")
435+
>>> format_compact_decimal(21000000, format_type="long", locale="mk")
435436
u'21 милион'
436437
437438
:param number: the number to format
@@ -469,11 +470,15 @@ def _get_compact_format(number, compact_format, locale, fraction_digits=0):
469470
# equal to the number of 0's in the pattern minus 1
470471
number = number / (magnitude // (10 ** (pattern.count("0") - 1)))
471472
# round to the number of fraction digits requested
472-
number = round(number, fraction_digits)
473+
rounded = round(number, fraction_digits)
473474
# if the remaining number is singular, use the singular format
474475
plural_form = locale.plural_form(abs(number))
475-
plural_form = plural_form if plural_form in compact_format else "other"
476+
if plural_form not in compact_format:
477+
plural_form = "other"
478+
if number == 1 and "1" in compact_format:
479+
plural_form = "1"
476480
format = compact_format[plural_form][str(magnitude)]
481+
number = rounded
477482
break
478483
return number, format
479484

@@ -960,17 +965,19 @@ def parse_precision(p):
960965
return NumberPattern(pattern, (pos_prefix, neg_prefix),
961966
(pos_suffix, neg_suffix), grouping,
962967
int_prec, frac_prec,
963-
exp_prec, exp_plus)
968+
exp_prec, exp_plus, number)
964969

965970

966971
class NumberPattern:
967972

968973
def __init__(self, pattern, prefix, suffix, grouping,
969-
int_prec, frac_prec, exp_prec, exp_plus):
974+
int_prec, frac_prec, exp_prec, exp_plus,
975+
number_pattern: str | None = None):
970976
# Metadata of the decomposed parsed pattern.
971977
self.pattern = pattern
972978
self.prefix = prefix
973979
self.suffix = suffix
980+
self.number_pattern = number_pattern
974981
self.grouping = grouping
975982
self.int_prec = int_prec
976983
self.frac_prec = frac_prec
@@ -1115,7 +1122,7 @@ def apply(
11151122

11161123
retval = ''.join([
11171124
self.prefix[is_negative],
1118-
number,
1125+
number if self.number_pattern != '' else '',
11191126
self.suffix[is_negative]])
11201127

11211128
if u'¤' in retval:

tests/test_numbers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,12 @@ def test_compact(self):
153153
assert numbers.format_compact_decimal(-123456789, format_type='short', locale='en_US') == u'-123M'
154154
assert numbers.format_compact_decimal(-123456789, format_type='long', locale='en_US') == u'-123 million'
155155
assert numbers.format_compact_decimal(2345678, locale='mk', format_type='long') == u'2 милиони'
156-
assert numbers.format_compact_decimal(21098765, locale='mk', format_type='long') == u'21 милион'
156+
assert numbers.format_compact_decimal(21000000, locale='mk', format_type='long') == u'21 милион'
157+
assert numbers.format_compact_decimal(21345, locale="gv", format_type="short") == u'21K'
158+
assert numbers.format_compact_decimal(1000, locale='it', format_type='long') == u'mille'
159+
assert numbers.format_compact_decimal(1234, locale='it', format_type='long') == u'1 mila'
160+
assert numbers.format_compact_decimal(1000, locale='fr', format_type='long') == u'mille'
161+
assert numbers.format_compact_decimal(1234, locale='fr', format_type='long') == u'1 millier'
157162

158163
class NumberParsingTestCase(unittest.TestCase):
159164

0 commit comments

Comments
 (0)