Files
intellecton/venv/lib/python3.12/site-packages/babel/__pycache__/plural.cpython-312.pyc
T

260 lines
31 KiB
Plaintext
Raw Normal View History

Ë
gÀj’Zã óè—UdZddlmZddlZddlZddlmZmZddlm Z m
Z
m Z dZ dZ
d7d„ZGd „d
«Zd8d „Z d9d „Zd8d
„Z d:d„Z d:d„Zd;d„ZGd„de«Zhd£Zdej2dej4«fdej2ddj7e«›d�«fdej2d«fdej2d«fdej2dej4«fgZded <d<d!„Z d= d>d"„Zd=d?d#„Z d@d$„Z!dAd%„Z" dBd&„Z#dCd'„Z$Gd(„d)«Z%d*„Z&d+„Z'd,„Z(Gd-„d.«Z)Gd/„d0e)«Z*Gd1„d2e)«Z+Gd3„d4e+«Z,Gd5„d6e)«Z-y)Dzœ
babel.numbers
~~~~~~~~~~~~~
CLDR Plural support. See UTS #35.
:copyright: (c) 2013-2026 by the Babel Team.
:license: BSD, see LICENSE for more details.
é)Ú annotationsN)ÚIterableÚMapping)ÚAnyÚCallableÚLiteral)ÚzeroÚoneÚtwoÚfewÚmanyÚotherrcó—t|«}t|«}t|t«r&||k(r|}nt j
t
|««}t|tj
«r�|j«}|j}|dkr|j|dnd}djd„|D««}|jd«}t|«}t|«} t|xsd«}
t|xsd«} ndx}x} x}
} dx} }
|||| |
| | |
fS)u÷Extract operands from a decimal, a float or an int, according to `CLDR rules`_.
The result is an 8-tuple (n, i, v, w, f, t, c, e), where those symbols are as follows:
====== ===============================================================
Symbol Value
------ ---------------------------------------------------------------
n absolute value of the source number (integer and decimals).
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 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-61/tr35-numbers.html#Operands
:param source: A real number
:type source: int|float|decimal.Decimal
:return: A n-i-v-w-f-t-c-e tuple
:rtype: tuple[decimal.Decimal, int, int, int, int, int, int, int]
rN©Úc3ó2K—|]}t|«–—Œy­w©N©Ústr)Ú.0Úds úO/home/antigravity/intellecton/venv/lib/python3.12/site-packages/babel/plural.pyú <genexpr>z#extract_operands.<locals>.<genexpr>Gsèø€Ò; aœ3˜qŸ6Ñ;ùs‚Ú0)
ÚabsÚintÚ
isinstanceÚfloatÚdecimalÚDecimalrÚas_tupleÚexponentÚdigitsÚjoinÚrstripÚlen)ÚsourceÚnÚiÚ dec_tupleÚexpÚfraction_digitsÚtrailingÚ no_trailingÚvÚwÚfÚtÚcÚes rÚextract_operandsr5s€ô6 ˆF‹ €AÜ ˆA‹€AÜ�!”UÔØ �Š6؉Aô—‘¤ A£Ó'ˆAä�!”W—_‘_Ô%Ø—J‘J“Lˆ Ø× Ñ ˆØ47¸!²G˜)×*Ñ*¨3¨4Ñ0ÀˆØ—7‘7Ñ;¨?Ô;Ó;ˆØ—o‘o cÓ*ˆ Ü �‹MˆÜ � Ó ˆÜ �’
˜AÓ ˆÜ � Ò ˜qÓ !‰àЈЈAÐ��AØ
€I€AˆØ ˆa��A�q˜!˜Q Ð !Ð!ócóz—eZdZdZdZd d„Zd
d„Ze dd„«Ze dd„«Z
e dd„«Z dd„Z dd „Z
dd
„Zy )Ú
PluralRuleafRepresents a set of language pluralization rules. The constructor
accepts a list of (tag, expr) tuples or a dict of `CLDR rules`_. The
resulting object is callable and accepts one parameter with a positive or
negative number (both integer and float) for the number that indicates the
plural form for a string and returns the tag for the format:
>>> rule = PluralRule({'one': 'n is 1'})
>>> rule(1)
'one'
>>> rule(2)
'other'
Currently the CLDR defines these tags: zero, one, two, few, many and
other where other is an implicit default. Rules should be mutually
exclusive; for a given numeric value, only one rule should apply (i.e.
the condition should only be true for one of the plural rule elements.
.. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Language_Plural_Rules
)ÚabstractÚ_funccój—t|t«r|j«}t«}g|_t |«D]t\}}|t vrtd|›�«‚||vrtd|›d�«‚|j|«t|«j}|sŒX|jj||f«Œvy)a$Initialize the rule instance.
:param rules: a list of ``(tag, expr)``) tuples with the rules
conforming to UTS #35 or a dict with the tags as keys
and expressions as values.
:raise RuleError: if the expression is malformed
z unknown tag ztag z defined twiceN) rrÚitemsÚsetr9ÚsortedÚ _plural_tagsÚ
ValueErrorÚaddÚ_ParserÚastÚappend)ÚselfÚrulesÚfoundÚkeyÚexprrCs rÚ__init__zPluralRule.__init__js¦€ô �eœWÔ %Ø—K‘K“MˆEÜ“ˆØ/1ˆŒ
Ü ›ò 1‰IˆC�Øœ,Ñ&Ü  <°¨wÐ!7Ó8Ð8ؘ‘Ü  4¨ w¨nÐ!=Ó>Ð>Ø �I‰I�cŒNܘ$“-×#Ñ#ˆCÚØ—
‘
×$Ñ$ c¨3 ZÕ0ñ 1r6có�‡—|jŠdjˆfd„tD««}dt|«j›d|›d�S)Nú, c3ó<•K—|]}|‰vsŒ|›d‰|›�–—Œy­w)z: Nr)rÚtagrFs €rrz&PluralRule.__repr__.<locals>.<genexpr>‚s'øèø€ÒX°CÈ3ÐRWÊ<˜C˜5  5¨¡: ,Ô/ÑXùsƒ �ú<ú ú>)rFr$r?ÚtypeÚ__name__)rEÚargsrFs @rÚ__repr__zPluralRule.__repr__€s@ø€Ø—
‘
ˆØ�y‰yÓX¼<ÔXÓXˆØ”4˜“:×&Ñ&Ð' q¨¨°Ð2Ð2r6có6—t|t«r|S||«S)a
Create a `PluralRule` instance for the given rules. If the rules
are a `PluralRule` object, that object is returned.
:param rules: the rules as list or dict, or a `PluralRule` object
:raise RuleError: if the expression is malformed
)rr8)ÚclsrFs rÚparsezPluralRule.parse…s€ô �eœZÔ (؈LÙ�5‹zÐr6có‚—t«j}|jD��cic]\}}|||«“Œc}}Scc}}w)zŸThe `PluralRule` as a dict of unicode plural rules.
>>> rule = PluralRule({'one': 'n is 1'})
>>> rule.rules
{'one': 'n is 1'}
)Ú_UnicodeCompilerÚcompiler9)rEÚ_compilerNrCs rrFzPluralRule.rules”s7€ô$Ó%×-Ñ-ˆØ37·=±=×A¡x s¨C�‘X˜c“]Ñ"ÓAÐAùÓAs¤;có:—td„|jD««S)z°A set of explicitly defined tags in this rule. The implicit default
``'other'`` rules is not part of this set unless there is an explicit
rule for it.
c3ó&K—|] }|d–—Œ y­w)rNr)rr)s rrz"PluralRule.tags.<locals>.<genexpr>¥sèø€Ò5 !˜˜1�Ñ5ùs‚)Ú frozensetr9©rEs rÚtagszPluralRule.tagsŸs€ô Ñ5 t§}¡}Ô5Ó5Ð5r6có—|jSr©r9r`s rÚ __getstate__zPluralRule.__getstate__§s €Ø�}‰}Ðr6có—||_yrrc)rEr9s rÚ __setstate__zPluralRule.__setstate__ªs €Ø ˆ�
r6có\—t|d«st|«|_|j|«S)Nr:)ÚhasattrÚ to_pythonr:)rEr(s rÚ__call__zPluralRule.__call__­s%€Ü�t˜WÔ%Ü" 4›ˆDŒJØ�z‰z˜!‹}Ðr6N)rFz-Mapping[str, str] | Iterable[tuple[str, str]]ÚreturnÚNone)rkr)rFú:Mapping[str, str] | Iterable[tuple[str, str]] | PluralRulerkr8)rkzMapping[str, str])rkzfrozenset[str])rkúlist[tuple[str, Any]])r9rnrkrl)r(úfloat | decimal.Decimalrkr)rSÚ
__module__Ú __qualname__Ú__doc__Ú __slots__rJrUÚ classmethodrXÚpropertyrFrardrfrjrr6rr8r8Ssw„ñð(&€Ió1ó,3ð
ð àIð ð
ò óð ðòBóðBðò6óð6óó!ôr6r8có
—t«j}dg}tj|«jD]"\}}|j ||«›d|›d�«Œ$|j dt z«dj|«S)a‚Convert a list/dict of rules or a `PluralRule` object into a JavaScript
function. This function depends on no external library:
>>> to_javascript({'one': 'n is 1'})
"(function(n) { return (n == 1) ? 'one' : 'other'; })"
Implementation detail: The function generated will probably evaluate
expressions involved into range operations multiple times. This has the
advantage that external helper functions are not required and is not a
big performance hit for these simple calculations.
:param rule: the rules as list or dict, or a `PluralRule` object
:raise RuleError: if the expression is malformed
z(function(n) { return ú ? ú : z%r; })r)Ú_JavaScriptCompilerr[r8rXr9rDÚ
_fallback_tagr$)ÚruleÚto_jsÚresultrNrCs rÚ
to_javascriptr~³sz€ô
Ó !× )Ñ )€EØ&Ð
'€FÜ×$Ñ$ TÓ*×3Ñ3ò4‰ˆˆSØ�
‰
™˜s›˜  C¨ w¨cÐ2Õ3ð4à
‡M�M�(œ]Ñ*Ô+Ø
�7‰7�6‹?Ðr6c ó„—ttttdœ}t «j
}ddg}t j|«jD]+\}}|jd||«›dt|«›�«Œ-|jdt›�«t dj|«dd «}t||«|d
S) a<Convert a list/dict of rules or a `PluralRule` object into a regular
Python function. This is useful in situations where you need a real
function and don't are about the actual rule object:
>>> func = to_python({'one': 'n is 1', 'few': 'n in 2..4'})
>>> func(1)
'one'
>>> func(3)
'few'
>>> func = to_python({'one': 'n in 1,11', 'few': 'n in 3..10,13..19'})
>>> func(11)
'one'
>>> func(15)
'few'
:param rule: the rules as list or dict, or a `PluralRule` object
:raise RuleError: if the expression is malformed
)ÚINÚWITHINÚMODr5zdef evaluate(n):z- n, i, v, w, f, t, c, e = extract_operands(n)z if (z
): return z return ú
z<rule>ÚexecÚevaluate)Ú
in_range_listÚwithin_range_listÚ cldr_modulor5Ú_PythonCompilerr[r8rXr9rDrrzr$Úeval)r{Ú namespaceÚto_python_funcr}rNrCÚcodes rririÊsÀô,Ü#ÜÜ,ñ €Iô %Ó&×.Ñ.€NàØ7ð€Fô×$Ñ$ TÓ*×3Ñ3òK‰ˆˆSð �
‰
˜™n¨SÓ1Ð2°*¼SÀ»X¸LÐIÕJðKð ‡M�M�Hœ]Ð-Ð.Ô/Ü �4—9‘9˜VÓ$ h°Ó 7€D܈ˆyÔØ �ZÑ Ð r6có¸—tj|«}|jthz}t «j
}t D�cgc] }||vsŒ|‘Œ c}j}dt|«›d�g}|jD](\}}|j||«›d||«›d�«Œ*|j|t«›d�«dj|«Scc}w)aThe plural rule as gettext expression. The gettext expression is
technically limited to integers and returns indices rather than tags.
>>> to_gettext({'one': 'n is 1', 'two': 'n is 2'})
'nplurals=3; plural=((n == 1) ? 0 : (n == 2) ? 1 : 2);'
:param rule: the rules as list or dict, or a `PluralRule` object
:raise RuleError: if the expression is malformed
z nplurals=z
; plural=(rwrxz);r) r8rXrarzÚ_GettextCompilerr[r?Úindexr&r9rDr$)r{Ú used_tagsr\rNÚ
_get_indexr}rCs rÚ
to_gettextr“ôsÍ€ô × Ñ ˜DÓ !€Dà— ‘ œ]˜OÑ+€IÜÓ!×)Ñ)€HÜ!-ÖB˜#°¸ Ò1A’#ÒB×HÑH€Jàœ#˜i›.Ð)¨Ð4Ð
5€FØ—M‘MòA‰ˆˆSØ�
‰
™ #›˜ s©:°c«?Ð*;¸3Ð?Õ@ðAà
‡M�M‘Z¤
Ó.Ð/¨rÐ2Ô3Ø
�7‰7�6‹?Ðùò
Cs Á CÁCcó:—|t|«k(xr t||«S)a™Integer range list test. This is the callback for the "in" operator
of the UTS #35 pluralization rule language:
>>> in_range_list(1, [(1, 3)])
True
>>> in_range_list(3, [(1, 3)])
True
>>> in_range_list(3, [(1, 3), (5, 8)])
True
>>> in_range_list(1.2, [(1, 4)])
False
>>> in_range_list(10, [(1, 4)])
False
>>> in_range_list(10, [(1, 4), (6, 8)])
False
)rr‡©ÚnumÚ
range_lists rr†r† s€ð( ”#�c“(‰?Ò AÔ0°°jÓAÐAr6có,‡—tˆfd„|D««S)a¶Float range test. This is the callback for the "within" operator
of the UTS #35 pluralization rule language:
>>> within_range_list(1, [(1, 3)])
True
>>> within_range_list(1.0, [(1, 3)])
True
>>> within_range_list(1.2, [(1, 4)])
True
>>> within_range_list(8.8, [(1, 4), (7, 15)])
True
>>> within_range_list(10, [(1, 4)])
False
>>> within_range_list(10.5, [(1, 4), (20, 30)])
False
c3óD•K—|]\}}|‰cxkxr|knc–—Œy­wrr)rÚmin_Úmax_r–s €rrz$within_range_list.<locals>.<genexpr>6s"øèø€Ò@¡z t¨Tˆt�sÖ"˜d×"Ð"Ñ@ùsƒ )Úanyr•s` rr‡r‡"sø€ô( Ó@°ZÔ@Ó @Ð@r6cóN—d}|dkr|dz}d}|dkr|dz}||z}|r|dz}|S)zîJavaish modulo. This modulo operator returns the value with the sign
of the dividend rather than the divisor like Python does:
>>> cldr_modulo(-3, 5)
-3
>>> cldr_modulo(-3, -5)
-3
>>> cldr_modulo(3, 5)
3
réÿÿÿÿér)ÚaÚbÚreverseÚrvs rrˆrˆ9sH€ð€G؈1‚uØ ˆR‰ˆØˆØˆ1‚uØ ˆR‰ˆØ
ˆQ‰€BÙØ
ˆb‰ˆØ
€Ir6có—eZdZdZy)Ú RuleErrorzRaised if a rule is malformed.N)rSrprqrrrr6rr¥r¥Ps„Ú(r6r¥>r3r4r1r)r(r2r/r0z\s+Úwordz"\b(and|or|is|(?:with)?in|not|mod|[rz])\bÚvaluez\d+Úsymbolz%|,|!=|=Úellipsisz\.{2,3}|\u2026z(list[tuple[str | None, re.Pattern[str]]]Ú_RULEScó>—|jd«d}g}d}t|«}||krntD]N\}}|j||«}|€Œ|j «}|r!|j ||j
«f«ntd||›�«‚||krŒn|ddd…S)Nú@rz3malformed CLDR pluralization rule. Got unexpected rž)Úsplitr&rªÚmatchÚendrDÚgroupr¥)Úsr}Úposr¯Útokr{r®s rÚ
tokenize_ruler´hs¶€Ø �‰�‹ �Q‰€AØ$&€FØ
€CÜ
ˆa‹&€CØ
�Š)Üò ^‰IˆC�Ø—J‘J˜q #Ó&ˆEØÑ Ø—i‘i“k�ÙØ—M‘M 3¨¯ © «
Ð"6Ô7Ùð
 ^ôÐQÐRSÐTWÑRXÐQ[Ð\Ó]Ð ]ð �‹)ð ‘$�B�$‰<Ðr6cóF—|xr|dd|k(xr|duxs |dd|k(S)NržrrŸr©ÚtokensÚtype_r§s rÚtest_next_tokenr¹zs8€ð
Ò Z�f˜R‘j ‘m uÑ,Ò Z°%¸4°-Ò2YÀ6È"Á:ÈaÁ=ÐTYÑCYÐZr6có>—t|||«r|j«Syr)r¹Úpopr¶s rÚ
skip_tokenr¼‚s€Ü�v˜u eÔ,Ø�z‰z‹|Ðð-r6có —d|ffS)Nr§r)r§s rÚ
value_noder¾‡s€Ø �U�HÐ Ðr6có
—|dfS)Nrr)Únames rÚ
ident_noderÁ‹s €Ø �ˆ8€Or6có
—d|fS)Nr—r)r—s rÚrange_list_noderÃ�s€ð ˜Ð #Ð#r6có —d|ffS)NÚnotr)r£s rÚnegaterÆ•s€Ø �2�%ˆ<Ðr6cóN—eZdZdZd„Zd
d„Zd„Zd„Zd„Zd„Z d „Z
d
„Z d „Z d „Z
y)rBuòInternal parser. This class can translate a single rule into an abstract
tree of tuples. It implements the following grammar::
condition = and_condition ('or' and_condition)*
('@integer' samples)?
('@decimal' samples)?
and_condition = relation ('and' relation)*
relation = is_relation | in_relation | within_relation
is_relation = expr 'is' ('not')? value
in_relation = expr (('not')? 'in' | '=' | '!=') range_list
within_relation = expr ('not')? 'within' range_list
expr = operand (('mod' | '%') value)?
operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
range_list = (range | value) (',' range_list)*
value = digit+
digit = 0|1|2|3|4|5|6|7|8|9
range = value'..'value
samples = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
sampleRange = decimalValue '~' decimalValue
decimalValue = value ('.' value)?
- Whitespace can occur between or around any of the above tokens.
- Rules should be mutually exclusive; for a given numeric value, only one
rule should apply (i.e. the condition should only be true for one of
the plural rule elements).
- The in and within relations can take comma-separated lists, such as:
'n in 3,5,7..15'.
- Samples are ignored.
The translator parses the expression on instantiation into an attribute
called `ast`.