Skip to content

Commit 90032bf

Browse files
committed
Add more type annotations to plural.py
1 parent a0c53c1 commit 90032bf

1 file changed

Lines changed: 17 additions & 18 deletions

File tree

babel/plural.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import decimal
1313
import re
1414
from collections.abc import Iterable, Mapping
15-
from typing import Any
15+
from typing import TYPE_CHECKING, Any, Callable
1616

1717
if TYPE_CHECKING:
1818
from typing_extensions import Literal
@@ -111,7 +111,7 @@ def __init__(self, rules: Mapping[str, str] | Iterable[tuple[str, str]]):
111111
and expressions as values.
112112
:raise RuleError: if the expression is malformed
113113
"""
114-
if isinstance(rules, dict):
114+
if isinstance(rules, Mapping):
115115
rules = rules.items()
116116
found = set()
117117
self.abstract: list[tuple[str, Any]] = []
@@ -173,7 +173,7 @@ def __call__(self, n: float | decimal.Decimal) -> str:
173173
return self._func(n)
174174

175175

176-
def to_javascript(rule):
176+
def to_javascript(rule: Mapping[str, str] | Iterable[tuple[str, str]] | PluralRule) -> str:
177177
"""Convert a list/dict of rules or a `PluralRule` object into a JavaScript
178178
function. This function depends on no external library:
179179
@@ -196,7 +196,7 @@ def to_javascript(rule):
196196
return ''.join(result)
197197

198198

199-
def to_python(rule):
199+
def to_python(rule: Mapping[str, str] | Iterable[tuple[str, str]] | PluralRule) -> Callable[[float | decimal.Decimal], str]:
200200
"""Convert a list/dict of rules or a `PluralRule` object into a regular
201201
Python function. This is useful in situations where you need a real
202202
function and don't are about the actual rule object:
@@ -236,7 +236,7 @@ def to_python(rule):
236236
return namespace['evaluate']
237237

238238

239-
def to_gettext(rule):
239+
def to_gettext(rule: Mapping[str, str] | Iterable[tuple[str, str]] | PluralRule) -> str:
240240
"""The plural rule as gettext expression. The gettext expression is
241241
technically limited to integers and returns indices rather than tags.
242242
@@ -259,7 +259,7 @@ def to_gettext(rule):
259259
return ''.join(result)
260260

261261

262-
def in_range_list(num, range_list):
262+
def in_range_list(num: float | decimal.Decimal, range_list: Iterable[Iterable[float | decimal.Decimal]]) -> bool:
263263
"""Integer range list test. This is the callback for the "in" operator
264264
of the UTS #35 pluralization rule language:
265265
@@ -279,7 +279,7 @@ def in_range_list(num, range_list):
279279
return num == int(num) and within_range_list(num, range_list)
280280

281281

282-
def within_range_list(num, range_list):
282+
def within_range_list(num: float | decimal.Decimal, range_list: Iterable[Iterable[float | decimal.Decimal]]) -> bool:
283283
"""Float range test. This is the callback for the "within" operator
284284
of the UTS #35 pluralization rule language:
285285
@@ -299,7 +299,7 @@ def within_range_list(num, range_list):
299299
return any(num >= min_ and num <= max_ for min_, max_ in range_list)
300300

301301

302-
def cldr_modulo(a, b):
302+
def cldr_modulo(a: float, b: float) -> float:
303303
"""Javaish modulo. This modulo operator returns the value with the sign
304304
of the dividend rather than the divisor like Python does:
305305
@@ -336,7 +336,7 @@ class RuleError(Exception):
336336
'e', # currently, synonym for ‘c’. however, may be redefined in the future.
337337
}
338338

339-
_RULES = [
339+
_RULES: list[tuple[str | None, re.Pattern[str]]] = [
340340
(None, re.compile(r'\s+', re.UNICODE)),
341341
('word', re.compile(fr'\b(and|or|is|(?:with)?in|not|mod|[{"".join(_VARS)}])\b')),
342342
('value', re.compile(r'\d+')),
@@ -345,9 +345,9 @@ class RuleError(Exception):
345345
]
346346

347347

348-
def tokenize_rule(s):
348+
def tokenize_rule(s: str) -> list[tuple[str, str]]:
349349
s = s.split('@')[0]
350-
result = []
350+
result: list[tuple[str, str]] = []
351351
pos = 0
352352
end = len(s)
353353
while pos < end:
@@ -363,30 +363,29 @@ def tokenize_rule(s):
363363
'Got unexpected %r' % s[pos])
364364
return result[::-1]
365365

366-
367-
def test_next_token(tokens, type_, value=None):
366+
def test_next_token(tokens: list[tuple[str, str]], type_: str, value: str | None = None) -> list[tuple[str, str]] | bool:
368367
return tokens and tokens[-1][0] == type_ and \
369368
(value is None or tokens[-1][1] == value)
370369

371370

372-
def skip_token(tokens, type_, value=None):
371+
def skip_token(tokens: list[tuple[str, str]], type_: str, value: str | None = None):
373372
if test_next_token(tokens, type_, value):
374373
return tokens.pop()
375374

376375

377-
def value_node(value):
376+
def value_node(value: int) -> tuple[Literal['value'], tuple[int]]:
378377
return 'value', (value, )
379378

380379

381-
def ident_node(name):
380+
def ident_node(name: str) -> tuple[str, tuple[()]]:
382381
return name, ()
383382

384383

385-
def range_list_node(range_list):
384+
def range_list_node(range_list: Iterable[Iterable[float | decimal.Decimal]]) -> tuple[Literal['range_list'], Iterable[Iterable[float | decimal.Decimal]]]:
386385
return 'range_list', range_list
387386

388387

389-
def negate(rv):
388+
def negate(rv: tuple[Any, ...]) -> tuple[Literal['not'], tuple[tuple[Any, ...]]]:
390389
return 'not', (rv,)
391390

392391

0 commit comments

Comments
 (0)