]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
plural: parse new c, e operands (otherwise unsupported though)
authorAarni Koskela <akx@iki.fi>
Tue, 25 Jan 2022 11:53:08 +0000 (13:53 +0200)
committerAarni Koskela <akx@iki.fi>
Fri, 8 Apr 2022 10:38:18 +0000 (13:38 +0300)
babel/plural.py
tests/test_plural.py

index 241629985e7c21fbc905d647081b23cb2fd1bf47..f06e90e4555a6b0df6a0cb92fc34a1d9c67b244a 100644 (file)
@@ -19,7 +19,7 @@ _fallback_tag = 'other'
 def extract_operands(source):
     """Extract operands from a decimal, a float or an int, according to `CLDR rules`_.
 
-    The result is a 6-tuple (n, i, v, w, f, t), where those symbols are as follows:
+    The result is a 8-tuple (n, i, v, w, f, t, c, e), where those symbols are as follows:
 
     ====== ===============================================================
     Symbol Value
@@ -30,14 +30,16 @@ def extract_operands(source):
     w      number of visible fraction digits in n, without trailing zeros.
     f      visible fractional digits in n, with trailing zeros.
     t      visible fractional digits in n, without trailing zeros.
+    c      compact decimal exponent value: exponent of the power of 10 used in compact decimal formatting.
+    e      currently, synonym for ā€˜c’. however, may be redefined in the future.
     ====== ===============================================================
 
-    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Operands
+    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-61/tr35-numbers.html#Operands
 
     :param source: A real number
     :type source: int|float|decimal.Decimal
-    :return: A n-i-v-w-f-t tuple
-    :rtype: tuple[decimal.Decimal, int, int, int, int, int]
+    :return: A n-i-v-w-f-t-c-e tuple
+    :rtype: tuple[decimal.Decimal, int, int, int, int, int, int, int]
     """
     n = abs(source)
     i = int(n)
@@ -69,7 +71,8 @@ def extract_operands(source):
         t = int(no_trailing or 0)
     else:
         v = w = f = t = 0
-    return n, i, v, w, f, t
+    c = e = 0  # TODO: c and e are not supported
+    return n, i, v, w, f, t, c, e
 
 
 class PluralRule(object):
@@ -216,7 +219,7 @@ def to_python(rule):
     to_python_func = _PythonCompiler().compile
     result = [
         'def evaluate(n):',
-        ' n, i, v, w, f, t = extract_operands(n)',
+        ' n, i, v, w, f, t, c, e = extract_operands(n)',
     ]
     for tag, ast in PluralRule.parse(rule).abstract:
         # the str() call is to coerce the tag to the native string.  It's
@@ -317,12 +320,20 @@ def cldr_modulo(a, b):
 class RuleError(Exception):
     """Raised if a rule is malformed."""
 
-_VARS = 'nivwft'
+_VARS = {
+    'n',  # absolute value of the source number.
+    'i',  # integer digits of n.
+    'v',  # number of visible fraction digits in n, with trailing zeros.*
+    'w',  # number of visible fraction digits in n, without trailing zeros.*
+    'f',  # visible fraction digits in n, with trailing zeros.*
+    't',  # visible fraction digits in n, without trailing zeros.*
+    'c',  # compact decimal exponent value: exponent of the power of 10 used in compact decimal formatting.
+    'e',  # currently, synonym for ā€˜c’. however, may be redefined in the future.
+}
 
 _RULES = [
     (None, re.compile(r'\s+', re.UNICODE)),
-    ('word', re.compile(r'\b(and|or|is|(?:with)?in|not|mod|[{0}])\b'
-                        .format(_VARS))),
+    ('word', re.compile(fr'\b(and|or|is|(?:with)?in|not|mod|[{"".join(_VARS)}])\b')),
     ('value', re.compile(r'\d+')),
     ('symbol', re.compile(r'%|,|!=|=')),
     ('ellipsis', re.compile(r'\.{2,3}|\u2026', re.UNICODE))  # U+2026: ELLIPSIS
@@ -525,6 +536,8 @@ class _Compiler(object):
     compile_w = lambda x: 'w'
     compile_f = lambda x: 'f'
     compile_t = lambda x: 't'
+    compile_c = lambda x: 'c'
+    compile_e = lambda x: 'e'
     compile_value = lambda x, v: str(v)
     compile_and = _binary_compiler('(%s && %s)')
     compile_or = _binary_compiler('(%s || %s)')
index dd28dc1e680e0c8611443c8eec44025846f915cd..b0230c79a2e4836d7d6977311c673b70e0eb1546 100644 (file)
@@ -255,13 +255,15 @@ EXTRACT_OPERANDS_TESTS = (
 
 @pytest.mark.parametrize('source,n,i,v,w,f,t', EXTRACT_OPERANDS_TESTS)
 def test_extract_operands(source, n, i, v, w, f, t):
-    e_n, e_i, e_v, e_w, e_f, e_t = plural.extract_operands(source)
+    e_n, e_i, e_v, e_w, e_f, e_t, e_c, e_e = plural.extract_operands(source)
     assert abs(e_n - decimal.Decimal(n)) <= EPSILON  # float-decimal conversion inaccuracy
     assert e_i == i
     assert e_v == v
     assert e_w == w
     assert e_f == f
     assert e_t == t
+    assert not e_c  # Not supported at present
+    assert not e_e  # Not supported at present
 
 
 @pytest.mark.parametrize('locale', ('ru', 'pl'))