Skip to content

Commit 483029f

Browse files
committed
More type annotations
1 parent 63e37ed commit 483029f

5 files changed

Lines changed: 62 additions & 35 deletions

File tree

babel/languages.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
from __future__ import annotations
2+
13
from babel.core import get_global
24

35

4-
def get_official_languages(territory, regional=False, de_facto=False):
6+
def get_official_languages(territory: str, regional: bool = False, de_facto: bool = False) -> tuple[str, ...]:
57
"""
68
Get the official language(s) for the given territory.
79
@@ -41,7 +43,7 @@ def get_official_languages(territory, regional=False, de_facto=False):
4143
return tuple(lang for _, lang in pairs)
4244

4345

44-
def get_territory_language_info(territory):
46+
def get_territory_language_info(territory: str) -> dict[str, dict[str, float | str | None]]:
4547
"""
4648
Get a dictionary of language information for a territory.
4749

babel/lists.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@
1313
:copyright: (c) 2015-2022 by the Babel Team.
1414
:license: BSD, see LICENSE for more details.
1515
"""
16+
from __future__ import annotations
17+
18+
from collections.abc import Sequence
19+
20+
from typing_extensions import Literal
1621

1722
from babel.core import Locale, default_locale
1823

1924
DEFAULT_LOCALE = default_locale()
2025

2126

22-
def format_list(lst, style='standard', locale=DEFAULT_LOCALE):
27+
def format_list(lst: Sequence[str],
28+
style: Literal["standard", "standard-short", "or", "or-short", "unit", "unit-short", "unit-narrow"] = 'standard',
29+
locale: Locale | str | None = DEFAULT_LOCALE) -> str:
2330
"""
2431
Format the items in `lst` as a list.
2532

babel/localedata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def resolve(self, data: Mapping[str | int | None, Any]) -> Mapping[str | int | N
219219
return data
220220

221221

222-
class LocaleDataDict(abc.MutableMapping[Any, Any]):
222+
class LocaleDataDict(abc.MutableMapping):
223223
"""Dictionary wrapper that automatically resolves aliases to the actual
224224
values.
225225
"""

babel/plural.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77
:copyright: (c) 2013-2022 by the Babel Team.
88
:license: BSD, see LICENSE for more details.
99
"""
10+
from __future__ import annotations
11+
1012
import decimal
1113
import re
12-
14+
from collections.abc import Iterable, Mapping
15+
from typing import Any
1316

1417
_plural_tags = ('zero', 'one', 'two', 'few', 'many', 'other')
1518
_fallback_tag = 'other'
1619

1720

18-
def extract_operands(source):
21+
def extract_operands(source: float | decimal.Decimal) -> tuple[decimal.Decimal, int, int, int, int, int, int, int]:
1922
"""Extract operands from a decimal, a float or an int, according to `CLDR rules`_.
2023
2124
The result is a 8-tuple (n, i, v, w, f, t, c, e), where those symbols are as follows:
@@ -97,7 +100,7 @@ class PluralRule:
97100

98101
__slots__ = ('abstract', '_func')
99102

100-
def __init__(self, rules):
103+
def __init__(self, rules: Mapping[str, str] | Iterable[tuple[str, str]]):
101104
"""Initialize the rule instance.
102105
103106
:param rules: a list of ``(tag, expr)``) tuples with the rules
@@ -108,7 +111,7 @@ def __init__(self, rules):
108111
if isinstance(rules, dict):
109112
rules = rules.items()
110113
found = set()
111-
self.abstract = []
114+
self.abstract: list[tuple[str, Any]] = []
112115
for key, expr in sorted(list(rules)):
113116
if key not in _plural_tags:
114117
raise ValueError(f"unknown tag {key!r}")
@@ -119,25 +122,25 @@ def __init__(self, rules):
119122
if ast:
120123
self.abstract.append((key, ast))
121124

122-
def __repr__(self):
125+
def __repr__(self) -> str:
123126
rules = self.rules
124127
args = ", ".join([f"{tag}: {rules[tag]}" for tag in _plural_tags if tag in rules])
125128
return f"<{type(self).__name__} {args!r}>"
126129

127130
@classmethod
128-
def parse(cls, rules):
131+
def parse(cls, rules: Mapping[str, str] | Iterable[tuple[str, str]] | PluralRule) -> PluralRule:
129132
"""Create a `PluralRule` instance for the given rules. If the rules
130133
are a `PluralRule` object, that object is returned.
131134
132135
:param rules: the rules as list or dict, or a `PluralRule` object
133136
:raise RuleError: if the expression is malformed
134137
"""
135-
if isinstance(rules, cls):
138+
if isinstance(rules, PluralRule):
136139
return rules
137140
return cls(rules)
138141

139142
@property
140-
def rules(self):
143+
def rules(self) -> Mapping[str, str]:
141144
"""The `PluralRule` as a dict of unicode plural rules.
142145
143146
>>> rule = PluralRule({'one': 'n is 1'})
@@ -147,18 +150,21 @@ def rules(self):
147150
_compile = _UnicodeCompiler().compile
148151
return {tag: _compile(ast) for tag, ast in self.abstract}
149152

150-
tags = property(lambda x: frozenset(i[0] for i in x.abstract), doc="""
151-
A set of explicitly defined tags in this rule. The implicit default
153+
@property
154+
def tags(self) -> frozenset[str]:
155+
"""A set of explicitly defined tags in this rule. The implicit default
152156
``'other'`` rules is not part of this set unless there is an explicit
153-
rule for it.""")
157+
rule for it.
158+
"""
159+
return frozenset(i[0] for i in self.abstract)
154160

155-
def __getstate__(self):
161+
def __getstate__(self) -> list[tuple[str, Any]]:
156162
return self.abstract
157163

158-
def __setstate__(self, abstract):
164+
def __setstate__(self, abstract: list[tuple[str, Any]]) -> None:
159165
self.abstract = abstract
160166

161-
def __call__(self, n):
167+
def __call__(self, n: float | decimal.Decimal) -> str:
162168
if not hasattr(self, '_func'):
163169
self._func = to_python(self)
164170
return self._func(n)

babel/support.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@
1010
:copyright: (c) 2013-2022 by the Babel Team.
1111
:license: BSD, see LICENSE for more details.
1212
"""
13+
from __future__ import annotations
1314

1415
import gettext
1516
import locale
17+
from datetime import date as _date, datetime as _datetime, time as _time, timedelta as _timedelta
18+
from typing import TYPE_CHECKING, Literal
19+
20+
from pytz import BaseTzInfo
1621

1722
from babel.core import Locale
18-
from babel.dates import format_date, format_datetime, format_time, \
19-
format_timedelta
20-
from babel.numbers import format_decimal, format_currency, format_compact_currency, \
21-
format_percent, format_scientific, format_compact_decimal
23+
from babel.dates import (format_date, format_datetime, format_time,
24+
format_timedelta)
25+
from babel.numbers import (format_compact_currency, format_compact_decimal,
26+
format_currency, format_decimal, format_percent,
27+
format_scientific)
2228

29+
if TYPE_CHECKING:
30+
from babel.dates import _PredefinedTimeFormat
2331

2432
class Format:
2533
"""Wrapper class providing the various date and number formatting functions
@@ -34,7 +42,7 @@ class Format:
3442
u'1.234'
3543
"""
3644

37-
def __init__(self, locale, tzinfo=None):
45+
def __init__(self, locale: Locale | str, tzinfo: BaseTzInfo | None = None):
3846
"""Initialize the formatter.
3947
4048
:param locale: the locale identifier or `Locale` instance
@@ -43,7 +51,7 @@ def __init__(self, locale, tzinfo=None):
4351
self.locale = Locale.parse(locale)
4452
self.tzinfo = tzinfo
4553

46-
def date(self, date=None, format='medium'):
54+
def date(self, date: _date | None = None, format: _PredefinedTimeFormat | str = 'medium') -> str:
4755
"""Return a date formatted according to the given pattern.
4856
4957
>>> from datetime import date
@@ -53,7 +61,7 @@ def date(self, date=None, format='medium'):
5361
"""
5462
return format_date(date, format, locale=self.locale)
5563

56-
def datetime(self, datetime=None, format='medium'):
64+
def datetime(self, datetime: _date | None = None, format: _PredefinedTimeFormat | str = 'medium') -> str:
5765
"""Return a date and time formatted according to the given pattern.
5866
5967
>>> from datetime import datetime
@@ -65,7 +73,7 @@ def datetime(self, datetime=None, format='medium'):
6573
return format_datetime(datetime, format, tzinfo=self.tzinfo,
6674
locale=self.locale)
6775

68-
def time(self, time=None, format='medium'):
76+
def time(self, time: _time | _datetime | None = None, format: _PredefinedTimeFormat | str = 'medium') -> str:
6977
"""Return a time formatted according to the given pattern.
7078
7179
>>> from datetime import datetime
@@ -76,8 +84,10 @@ def time(self, time=None, format='medium'):
7684
"""
7785
return format_time(time, format, tzinfo=self.tzinfo, locale=self.locale)
7886

79-
def timedelta(self, delta, granularity='second', threshold=.85,
80-
format='long', add_direction=False):
87+
def timedelta(self, delta: _timedelta | int,
88+
granularity: Literal["year", "month", "week", "day", "hour", "minute", "second"] = 'second',
89+
threshold: float = .85, format: Literal["narrow", "short", "medium", "long"] = 'long',
90+
add_direction: bool = False) -> str:
8191
"""Return a time delta according to the rules of the given locale.
8292
8393
>>> from datetime import timedelta
@@ -90,7 +100,7 @@ def timedelta(self, delta, granularity='second', threshold=.85,
90100
format=format, add_direction=add_direction,
91101
locale=self.locale)
92102

93-
def number(self, number):
103+
def number(self, number: float | decimal.Decimal | str) -> str:
94104
"""Return an integer number formatted for the locale.
95105
96106
>>> fmt = Format('en_US')
@@ -99,7 +109,7 @@ def number(self, number):
99109
"""
100110
return format_decimal(number, locale=self.locale)
101111

102-
def decimal(self, number, format=None):
112+
def decimal(self, number: float | decimal.Decimal | str, format: str | None = None) -> str:
103113
"""Return a decimal number formatted for the locale.
104114
105115
>>> fmt = Format('en_US')
@@ -108,7 +118,8 @@ def decimal(self, number, format=None):
108118
"""
109119
return format_decimal(number, format, locale=self.locale)
110120

111-
def compact_decimal(self, number, format_type='short', fraction_digits=0):
121+
def compact_decimal(self, number: float | decimal.Decimal | str,
122+
format_type: Literal["short", "long"] = 'short', fraction_digits: int = 0) -> str:
112123
"""Return a number formatted in compact form for the locale.
113124
114125
>>> fmt = Format('en_US')
@@ -119,19 +130,20 @@ def compact_decimal(self, number, format_type='short', fraction_digits=0):
119130
fraction_digits=fraction_digits,
120131
locale=self.locale)
121132

122-
def currency(self, number, currency):
133+
def currency(self, number: float | decimal.Decimal | str, currency: str) -> str:
123134
"""Return a number in the given currency formatted for the locale.
124135
"""
125136
return format_currency(number, currency, locale=self.locale)
126137

127-
def compact_currency(self, number, currency, format_type='short', fraction_digits=0):
138+
def compact_currency(self, number: float | decimal.Decimal | str, currency: str,
139+
format_type: Literal['short', 'long'] = 'short', fraction_digits: int = 0) -> str:
128140
"""Return a number in the given currency formatted for the locale
129141
using the compact number format.
130142
"""
131143
return format_compact_currency(number, currency, format_type=format_type,
132144
fraction_digits=fraction_digits, locale=self.locale)
133145

134-
def percent(self, number, format=None):
146+
def percent(self, number: float | decimal.Decimal | str, format: str | None = None) -> str:
135147
"""Return a number formatted as percentage for the locale.
136148
137149
>>> fmt = Format('en_US')
@@ -140,7 +152,7 @@ def percent(self, number, format=None):
140152
"""
141153
return format_percent(number, format, locale=self.locale)
142154

143-
def scientific(self, number):
155+
def scientific(self, number: float | decimal.Decimal | str) -> str:
144156
"""Return a number formatted using scientific notation for the locale.
145157
"""
146158
return format_scientific(number, locale=self.locale)

0 commit comments

Comments
 (0)