From: Aarni Koskela Date: Tue, 25 Jan 2022 11:53:08 +0000 (+0200) Subject: plural: parse new c, e operands (otherwise unsupported though) X-Git-Tag: v2.10.0~8^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98620495670fa0e046d2e2e57a7a75dc8643119c;p=thirdparty%2Fbabel.git plural: parse new c, e operands (otherwise unsupported though) --- diff --git a/babel/plural.py b/babel/plural.py index 24162998..f06e90e4 100644 --- a/babel/plural.py +++ b/babel/plural.py @@ -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)') diff --git a/tests/test_plural.py b/tests/test_plural.py index dd28dc1e..b0230c79 100644 --- a/tests/test_plural.py +++ b/tests/test_plural.py @@ -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'))