Skip to content

Commit db48791

Browse files
authored
Merge pull request #1170 from python-babel/small-cleanup
Small cleanups
2 parents 8e10fb5 + 7a576d2 commit db48791

37 files changed

+199
-146
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.8.2
3+
rev: v0.9.1
44
hooks:
55
- id: ruff
66
args:

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Details can be found in the HTML files in the ``docs`` folder.
99

1010
For more information please visit the Babel web site:
1111

12-
http://babel.pocoo.org/
12+
https://babel.pocoo.org/
1313

1414
Join the chat at https://gitter.im/python-babel/babel
1515

babel/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
__all__ = [
3131
'Locale',
3232
'UnknownLocaleError',
33+
'__version__',
3334
'default_locale',
3435
'get_locale_identifier',
3536
'negotiate_locale',

babel/core.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@
1818
from babel import localedata
1919
from babel.plural import PluralRule
2020

21-
__all__ = ['UnknownLocaleError', 'Locale', 'default_locale', 'negotiate_locale',
22-
'parse_locale']
21+
__all__ = [
22+
'Locale',
23+
'UnknownLocaleError',
24+
'default_locale',
25+
'get_global',
26+
'get_locale_identifier',
27+
'negotiate_locale',
28+
'parse_locale',
29+
]
2330

2431
if TYPE_CHECKING:
2532
from typing_extensions import Literal, TypeAlias
@@ -259,6 +266,7 @@ def negotiate(
259266
:param preferred: the list of locale identifiers preferred by the user
260267
:param available: the list of locale identifiers available
261268
:param aliases: a dictionary of aliases for locale identifiers
269+
:param sep: separator for parsing; e.g. Windows tends to use '-' instead of '_'.
262270
"""
263271
identifier = negotiate_locale(preferred, available, sep=sep,
264272
aliases=aliases)
@@ -575,7 +583,7 @@ def languages(self) -> localedata.LocaleDataDict:
575583
>>> Locale('de', 'DE').languages['ja']
576584
u'Japanisch'
577585
578-
See `ISO 639 <http://www.loc.gov/standards/iso639-2/>`_ for
586+
See `ISO 639 <https://www.loc.gov/standards/iso639-2/>`_ for
579587
more information.
580588
"""
581589
return self._data['languages']
@@ -587,7 +595,7 @@ def scripts(self) -> localedata.LocaleDataDict:
587595
>>> Locale('en', 'US').scripts['Hira']
588596
u'Hiragana'
589597
590-
See `ISO 15924 <http://www.evertype.com/standards/iso15924/>`_
598+
See `ISO 15924 <https://www.unicode.org/iso15924/>`_
591599
for more information.
592600
"""
593601
return self._data['scripts']
@@ -599,7 +607,7 @@ def territories(self) -> localedata.LocaleDataDict:
599607
>>> Locale('es', 'CO').territories['DE']
600608
u'Alemania'
601609
602-
See `ISO 3166 <http://www.iso.org/iso/en/prods-services/iso3166ma/>`_
610+
See `ISO 3166 <https://en.wikipedia.org/wiki/ISO_3166>`_
603611
for more information.
604612
"""
605613
return self._data['territories']

babel/dates.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1935,14 +1935,18 @@ def match_skeleton(skeleton: str, options: Iterable[str], allow_different_fields
19351935
:type skeleton: str
19361936
:param options: An iterable of other skeletons to match against
19371937
:type options: Iterable[str]
1938+
:param allow_different_fields: Whether to allow a match that uses different fields
1939+
than the skeleton requested.
1940+
:type allow_different_fields: bool
1941+
19381942
:return: The closest skeleton match, or if no match was found, None.
19391943
:rtype: str|None
19401944
"""
19411945

19421946
# TODO: maybe implement pattern expansion?
19431947

19441948
# Based on the implementation in
1945-
# http://source.icu-project.org/repos/icu/icu4j/trunk/main/classes/core/src/com/ibm/icu/text/DateIntervalInfo.java
1949+
# https://github.com/unicode-org/icu/blob/main/icu4j/main/core/src/main/java/com/ibm/icu/text/DateIntervalInfo.java
19461950

19471951
# Filter out falsy values and sort for stability; when `interval_formats` is passed in, there may be a None key.
19481952
options = sorted(option for option in options if option)

babel/messages/catalog.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@
2929

3030
_MessageID: TypeAlias = str | tuple[str, ...] | list[str]
3131

32-
__all__ = ['Message', 'Catalog', 'TranslationError']
32+
__all__ = [
33+
'DEFAULT_HEADER',
34+
'PYTHON_FORMAT',
35+
'Catalog',
36+
'Message',
37+
'TranslationError',
38+
]
39+
3340

3441
def get_close_matches(word, possibilities, n=3, cutoff=0.6):
3542
"""A modified version of ``difflib.get_close_matches``.
@@ -42,7 +49,7 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6):
4249
if not 0.0 <= cutoff <= 1.0: # pragma: no cover
4350
raise ValueError(f"cutoff must be in [0.0, 1.0]: {cutoff!r}")
4451
result = []
45-
s = SequenceMatcher(autojunk=False) # only line changed from difflib.py
52+
s = SequenceMatcher(autojunk=False) # only line changed from difflib.py
4653
s.set_seq2(word)
4754
for x in possibilities:
4855
s.set_seq1(x)
@@ -274,6 +281,14 @@ def parse_separated_header(value: str) -> dict[str, str]:
274281
return dict(m.get_params())
275282

276283

284+
def _force_text(s: str | bytes, encoding: str = 'utf-8', errors: str = 'strict') -> str:
285+
if isinstance(s, str):
286+
return s
287+
if isinstance(s, bytes):
288+
return s.decode(encoding, errors)
289+
return str(s)
290+
291+
277292
class Catalog:
278293
"""Representation of a message catalog."""
279294

@@ -428,46 +443,39 @@ def _set_header_comment(self, string: str | None) -> None:
428443
""")
429444

430445
def _get_mime_headers(self) -> list[tuple[str, str]]:
431-
headers: list[tuple[str, str]] = []
432-
headers.append(("Project-Id-Version", f"{self.project} {self.version}"))
433-
headers.append(('Report-Msgid-Bugs-To', self.msgid_bugs_address))
434-
headers.append(('POT-Creation-Date',
435-
format_datetime(self.creation_date, 'yyyy-MM-dd HH:mmZ',
436-
locale='en')))
437446
if isinstance(self.revision_date, (datetime.datetime, datetime.time, int, float)):
438-
headers.append(('PO-Revision-Date',
439-
format_datetime(self.revision_date,
440-
'yyyy-MM-dd HH:mmZ', locale='en')))
447+
revision_date = format_datetime(self.revision_date, 'yyyy-MM-dd HH:mmZ', locale='en')
441448
else:
442-
headers.append(('PO-Revision-Date', self.revision_date))
443-
headers.append(('Last-Translator', self.last_translator))
449+
revision_date = self.revision_date
450+
451+
language_team = self.language_team
452+
if self.locale_identifier and 'LANGUAGE' in language_team:
453+
language_team = language_team.replace('LANGUAGE', str(self.locale_identifier))
454+
455+
headers: list[tuple[str, str]] = [
456+
("Project-Id-Version", f"{self.project} {self.version}"),
457+
('Report-Msgid-Bugs-To', self.msgid_bugs_address),
458+
('POT-Creation-Date', format_datetime(self.creation_date, 'yyyy-MM-dd HH:mmZ', locale='en')),
459+
('PO-Revision-Date', revision_date),
460+
('Last-Translator', self.last_translator),
461+
]
444462
if self.locale_identifier:
445463
headers.append(('Language', str(self.locale_identifier)))
446-
if self.locale_identifier and ('LANGUAGE' in self.language_team):
447-
headers.append(('Language-Team',
448-
self.language_team.replace('LANGUAGE',
449-
str(self.locale_identifier))))
450-
else:
451-
headers.append(('Language-Team', self.language_team))
464+
headers.append(('Language-Team', language_team))
452465
if self.locale is not None:
453466
headers.append(('Plural-Forms', self.plural_forms))
454-
headers.append(('MIME-Version', '1.0'))
455-
headers.append(("Content-Type", f"text/plain; charset={self.charset}"))
456-
headers.append(('Content-Transfer-Encoding', '8bit'))
457-
headers.append(("Generated-By", f"Babel {VERSION}\n"))
467+
headers += [
468+
('MIME-Version', '1.0'),
469+
("Content-Type", f"text/plain; charset={self.charset}"),
470+
('Content-Transfer-Encoding', '8bit'),
471+
("Generated-By", f"Babel {VERSION}\n"),
472+
]
458473
return headers
459474

460-
def _force_text(self, s: str | bytes, encoding: str = 'utf-8', errors: str = 'strict') -> str:
461-
if isinstance(s, str):
462-
return s
463-
if isinstance(s, bytes):
464-
return s.decode(encoding, errors)
465-
return str(s)
466-
467475
def _set_mime_headers(self, headers: Iterable[tuple[str, str]]) -> None:
468476
for name, value in headers:
469-
name = self._force_text(name.lower(), encoding=self.charset)
470-
value = self._force_text(value, encoding=self.charset)
477+
name = _force_text(name.lower(), encoding=self.charset)
478+
value = _force_text(value, encoding=self.charset)
471479
if name == 'project-id-version':
472480
parts = value.split(' ')
473481
self.project = ' '.join(parts[:-1])
@@ -824,6 +832,9 @@ def update(
824832
825833
:param template: the reference catalog, usually read from a POT file
826834
:param no_fuzzy_matching: whether to use fuzzy matching of message IDs
835+
:param update_header_comment: whether to copy the header comment from the template
836+
:param keep_user_comments: whether to keep user comments from the old catalog
837+
:param update_creation_date: whether to copy the creation date from the template
827838
"""
828839
messages = self._messages
829840
remaining = messages.copy()

babel/messages/extract.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,20 @@ def extract_from_file(
325325
options, strip_comment_tags))
326326

327327

328-
def _match_messages_against_spec(lineno: int, messages: list[str|None], comments: list[str],
329-
fileobj: _FileObj, spec: tuple[int|tuple[int, str], ...]):
328+
def _match_messages_against_spec(
329+
lineno: int,
330+
messages: list[str | None],
331+
comments: list[str],
332+
fileobj: _FileObj,
333+
spec: tuple[int | tuple[int, str], ...],
334+
):
330335
translatable = []
331336
context = None
332337

333338
# last_index is 1 based like the keyword spec
334339
last_index = len(messages)
335340
for index in spec:
336-
if isinstance(index, tuple): # (n, 'c')
341+
if isinstance(index, tuple): # (n, 'c')
337342
context = messages[index[0] - 1]
338343
continue
339344
if last_index < index:
@@ -421,7 +426,6 @@ def extract(
421426
:returns: iterable of tuples of the form ``(lineno, message, comments, context)``
422427
:rtype: Iterable[tuple[int, str|tuple[str], list[str], str|None]
423428
"""
424-
func = None
425429
if callable(method):
426430
func = method
427431
elif ':' in method or '.' in method:
@@ -622,9 +626,7 @@ def extract_python(
622626
elif tok == NAME and value in keywords:
623627
funcname = value
624628

625-
if (current_fstring_start is not None
626-
and tok not in {FSTRING_START, FSTRING_MIDDLE}
627-
):
629+
if current_fstring_start is not None and tok not in {FSTRING_START, FSTRING_MIDDLE}:
628630
# In Python 3.12, tokens other than FSTRING_* mean the
629631
# f-string is dynamic, so we don't wan't to extract it.
630632
# And if it's FSTRING_END, we've already handled it above.

babel/messages/frontend.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ def _configure_command(self, cmdname, argv):
961961
usage=self.usage % (cmdname, ''),
962962
description=self.commands[cmdname],
963963
)
964-
as_args = getattr(cmdclass, "as_args", ())
964+
as_args: str | None = getattr(cmdclass, "as_args", None)
965965
for long, short, help in cmdclass.user_options:
966966
name = long.strip("=")
967967
default = getattr(cmdinst, name.replace("-", "_"))
@@ -1012,6 +1012,7 @@ def parse_mapping_cfg(fileobj, filename=None):
10121012
10131013
:param fileobj: a readable file-like object containing the configuration
10141014
text to parse
1015+
:param filename: the name of the file being parsed, for error messages
10151016
"""
10161017
extractors = {}
10171018
method_map = []

babel/messages/jslexer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def tokenize(source: str, jsx: bool = True, dotted: bool = True, template_string
162162
"""
163163
Tokenize JavaScript/JSX source. Returns a generator of tokens.
164164
165+
:param source: The JavaScript source to tokenize.
165166
:param jsx: Enable (limited) JSX parsing.
166167
:param dotted: Read dotted names as single name token.
167168
:param template_string: Support ES6 template strings

babel/messages/plurals.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
"""
1010
from __future__ import annotations
1111

12-
from operator import itemgetter
13-
1412
from babel.core import Locale, default_locale
1513

1614
# XXX: remove this file, duplication with babel.plural
@@ -209,12 +207,21 @@ class _PluralTuple(tuple):
209207
"""A tuple with plural information."""
210208

211209
__slots__ = ()
212-
num_plurals = property(itemgetter(0), doc="""
213-
The number of plurals used by the locale.""")
214-
plural_expr = property(itemgetter(1), doc="""
215-
The plural expression used by the locale.""")
216-
plural_forms = property(lambda x: 'nplurals={}; plural={};'.format(*x), doc="""
217-
The plural expression used by the catalog or locale.""")
210+
211+
@property
212+
def num_plurals(self) -> int:
213+
"""The number of plurals used by the locale."""
214+
return self[0]
215+
216+
@property
217+
def plural_expr(self) -> str:
218+
"""The plural expression used by the locale."""
219+
return self[1]
220+
221+
@property
222+
def plural_forms(self) -> str:
223+
"""The plural expression used by the catalog or locale."""
224+
return f'nplurals={self[0]}; plural={self[1]};'
218225

219226
def __str__(self) -> str:
220227
return self.plural_forms

0 commit comments

Comments
 (0)