Skip to content

Commit cf405e2

Browse files
authored
Merge pull request #949 from python-babel/ruffify
Add ruff for linting
2 parents 6e02940 + d14f956 commit cf405e2

47 files changed

Lines changed: 785 additions & 709 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
repos:
2+
- repo: https://github.com/charliermarsh/ruff-pre-commit
3+
rev: v0.0.224
4+
hooks:
5+
- id: ruff
6+
args:
7+
- --fix
8+
- --force-exclude
29
- repo: https://github.com/pre-commit/pre-commit-hooks
310
rev: v4.4.0
411
hooks:

babel/core.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
_global_data = None
4747
_default_plural_rule = PluralRule({})
4848

49+
4950
def _raise_no_data_error():
5051
raise RuntimeError('The babel data files are not available. '
5152
'This usually happens because you are using '
@@ -383,10 +384,12 @@ def __eq__(self, other: object) -> bool:
383384
for key in ('language', 'territory', 'script', 'variant'):
384385
if not hasattr(other, key):
385386
return False
386-
return (self.language == getattr(other, 'language')) and \
387-
(self.territory == getattr(other, 'territory')) and \
388-
(self.script == getattr(other, 'script')) and \
389-
(self.variant == getattr(other, 'variant'))
387+
return (
388+
self.language == getattr(other, 'language') and # noqa: B009
389+
self.territory == getattr(other, 'territory') and # noqa: B009
390+
self.script == getattr(other, 'script') and # noqa: B009
391+
self.variant == getattr(other, 'variant') # noqa: B009
392+
)
390393

391394
def __ne__(self, other: object) -> bool:
392395
return not self.__eq__(other)

babel/dates.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
pytz = None
2828
import zoneinfo
2929

30+
import datetime
3031
from bisect import bisect_right
3132
from collections.abc import Iterable
32-
import datetime
3333

3434
from babel import localtime
3535
from babel.core import Locale, default_locale, get_global
@@ -49,7 +49,7 @@
4949
# empty set characters ( U+2205 )."
5050
# - https://www.unicode.org/reports/tr35/tr35-dates.html#Metazone_Names
5151

52-
NO_INHERITANCE_MARKER = u'\u2205\u2205\u2205'
52+
NO_INHERITANCE_MARKER = '\u2205\u2205\u2205'
5353

5454

5555
if pytz:
@@ -247,13 +247,13 @@ def get_timezone(zone: str | datetime.tzinfo | None = None) -> datetime.tzinfo:
247247
if pytz:
248248
try:
249249
return pytz.timezone(zone)
250-
except pytz.UnknownTimeZoneError as exc:
250+
except pytz.UnknownTimeZoneError as exc: # noqa: F841
251251
pass
252252
else:
253253
assert zoneinfo
254254
try:
255255
return zoneinfo.ZoneInfo(zone)
256-
except zoneinfo.ZoneInfoNotFoundError as exc:
256+
except zoneinfo.ZoneInfoNotFoundError as exc: # noqa: F841
257257
pass
258258

259259
raise LookupError(f"Unknown timezone {zone}") from exc
@@ -558,11 +558,11 @@ def get_timezone_gmt(
558558
if return_z and hours == 0 and seconds == 0:
559559
return 'Z'
560560
elif seconds == 0 and width == 'iso8601_short':
561-
return u'%+03d' % hours
561+
return '%+03d' % hours
562562
elif width == 'short' or width == 'iso8601_short':
563-
pattern = u'%+03d%02d'
563+
pattern = '%+03d%02d'
564564
elif width == 'iso8601':
565-
pattern = u'%+03d:%02d'
565+
pattern = '%+03d:%02d'
566566
else:
567567
pattern = locale.zone_formats['gmt'] % '%+03d:%02d'
568568
return pattern % (hours, seconds // 60)
@@ -1083,10 +1083,10 @@ def _iter_patterns(a_unit):
10831083
break
10841084
# This really should not happen
10851085
if pattern is None:
1086-
return u''
1086+
return ''
10871087
return pattern.replace('{0}', str(value))
10881088

1089-
return u''
1089+
return ''
10901090

10911091

10921092
def _format_fallback_interval(
@@ -1349,8 +1349,7 @@ def parse_date(
13491349
month_idx = format_str.index('l')
13501350
day_idx = format_str.index('d')
13511351

1352-
indexes = [(year_idx, 'Y'), (month_idx, 'M'), (day_idx, 'D')]
1353-
indexes.sort()
1352+
indexes = sorted([(year_idx, 'Y'), (month_idx, 'M'), (day_idx, 'D')])
13541353
indexes = {item[1]: idx for idx, item in enumerate(indexes)}
13551354

13561355
# FIXME: this currently only supports numbers, but should also support month
@@ -1399,8 +1398,7 @@ def parse_time(
13991398
min_idx = format_str.index('m')
14001399
sec_idx = format_str.index('s')
14011400

1402-
indexes = [(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')]
1403-
indexes.sort()
1401+
indexes = sorted([(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')])
14041402
indexes = {item[1]: idx for idx, item in enumerate(indexes)}
14051403

14061404
# TODO: support time zones
@@ -1436,7 +1434,7 @@ def __str__(self) -> str:
14361434
return pat
14371435

14381436
def __mod__(self, other: DateTimeFormat) -> str:
1439-
if type(other) is not DateTimeFormat:
1437+
if not isinstance(other, DateTimeFormat):
14401438
return NotImplemented
14411439
return self.format % other
14421440

@@ -1829,7 +1827,7 @@ def parse_pattern(pattern: str) -> DateTimePattern:
18291827
18301828
:param pattern: the formatting pattern to parse
18311829
"""
1832-
if type(pattern) is DateTimePattern:
1830+
if isinstance(pattern, DateTimePattern):
18331831
return pattern
18341832

18351833
if pattern in _pattern_cache:
@@ -1849,7 +1847,7 @@ def parse_pattern(pattern: str) -> DateTimePattern:
18491847
else:
18501848
raise NotImplementedError(f"Unknown token type: {tok_type}")
18511849

1852-
_pattern_cache[pattern] = pat = DateTimePattern(pattern, u''.join(result))
1850+
_pattern_cache[pattern] = pat = DateTimePattern(pattern, ''.join(result))
18531851
return pat
18541852

18551853

@@ -1884,7 +1882,7 @@ def append_field():
18841882
fieldchar[0] = ''
18851883
fieldnum[0] = 0
18861884

1887-
for idx, char in enumerate(pattern.replace("''", '\0')):
1885+
for char in pattern.replace("''", '\0'):
18881886
if quotebuf is None:
18891887
if char == "'": # quote started
18901888
if fieldchar[0]:

babel/localtime/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
:license: BSD, see LICENSE for more details.
1010
"""
1111

12+
import datetime
1213
import sys
1314
import time
14-
import datetime
1515
from threading import RLock
1616

1717
if sys.platform == 'win32':

babel/localtime/_helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def _get_tzinfo(tzenv: str):
2424

2525
return None
2626

27+
2728
def _get_tzinfo_or_raise(tzenv: str):
2829
tzinfo = _get_tzinfo(tzenv)
2930
if tzinfo is None:

babel/localtime/_unix.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import datetime
12
import os
23
import re
34

4-
import datetime
5-
65
from babel.localtime._helpers import (
6+
_get_tzinfo,
77
_get_tzinfo_from_file,
88
_get_tzinfo_or_raise,
9-
_get_tzinfo,
109
)
1110

11+
1212
def _tz_from_env(tzenv: str) -> datetime.tzinfo:
1313
if tzenv[0] == ':':
1414
tzenv = tzenv[1:]

babel/localtime/_win32.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
winreg = None
77

88
import datetime
9+
from typing import Any, Dict, cast
10+
911
from babel.core import get_global
1012
from babel.localtime._helpers import _get_tzinfo_or_raise
11-
from typing import Any, Dict, cast
1213

1314
# When building the cldr data on windows this module gets imported.
1415
# Because at that point there is no global.dat yet this call will

babel/messages/catalog.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,20 @@
99
"""
1010
from __future__ import annotations
1111

12+
import datetime
1213
import re
13-
1414
from collections import OrderedDict
15-
from collections.abc import Generator, Iterable, Iterator
16-
import datetime
15+
from collections.abc import Iterable, Iterator
16+
from copy import copy
1717
from difflib import get_close_matches
1818
from email import message_from_string
19-
from copy import copy
2019
from typing import TYPE_CHECKING
2120

2221
from babel import __version__ as VERSION
2322
from babel.core import Locale, UnknownLocaleError
2423
from babel.dates import format_datetime
2524
from babel.messages.plurals import get_plural
26-
from babel.util import distinct, LOCALTZ, FixedOffsetTimezone, _cmp
25+
from babel.util import LOCALTZ, FixedOffsetTimezone, _cmp, distinct
2726

2827
if TYPE_CHECKING:
2928
from typing_extensions import TypeAlias
@@ -81,7 +80,7 @@ class Message:
8180
def __init__(
8281
self,
8382
id: _MessageID,
84-
string: _MessageID | None = u'',
83+
string: _MessageID | None = '',
8584
locations: Iterable[tuple[str, int]] = (),
8685
flags: Iterable[str] = (),
8786
auto_comments: Iterable[str] = (),
@@ -108,7 +107,7 @@ def __init__(
108107
"""
109108
self.id = id
110109
if not string and self.pluralizable:
111-
string = (u'', u'')
110+
string = ('', '')
112111
self.string = string
113112
self.locations = list(distinct(locations))
114113
self.flags = set(flags)
@@ -234,13 +233,14 @@ class TranslationError(Exception):
234233
translations are encountered."""
235234

236235

237-
DEFAULT_HEADER = u"""\
236+
DEFAULT_HEADER = """\
238237
# Translations template for PROJECT.
239238
# Copyright (C) YEAR ORGANIZATION
240239
# This file is distributed under the same license as the PROJECT project.
241240
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
242241
#"""
243242

243+
244244
def parse_separated_header(value: str) -> dict[str, str]:
245245
# Adapted from https://peps.python.org/pep-0594/#cgi
246246
from email.message import Message
@@ -445,7 +445,7 @@ def _set_mime_headers(self, headers: Iterable[tuple[str, str]]) -> None:
445445
value = self._force_text(value, encoding=self.charset)
446446
if name == 'project-id-version':
447447
parts = value.split(' ')
448-
self.project = u' '.join(parts[:-1])
448+
self.project = ' '.join(parts[:-1])
449449
self.version = parts[-1]
450450
elif name == 'report-msgid-bugs-to':
451451
self.msgid_bugs_address = value
@@ -592,7 +592,7 @@ def __iter__(self) -> Iterator[Message]:
592592
flags = set()
593593
if self.fuzzy:
594594
flags |= {'fuzzy'}
595-
yield Message(u'', '\n'.join(buf), flags=flags)
595+
yield Message('', '\n'.join(buf), flags=flags)
596596
for key in self._messages:
597597
yield self._messages[key]
598598

@@ -737,7 +737,8 @@ def delete(self, id: _MessageID, context: str | None = None) -> None:
737737
if key in self._messages:
738738
del self._messages[key]
739739

740-
def update(self,
740+
def update(
741+
self,
741742
template: Catalog,
742743
no_fuzzy_matching: bool = False,
743744
update_header_comment: bool = False,
@@ -832,7 +833,7 @@ def _merge(message: Message, oldkey: tuple[str, str] | str, newkey: tuple[str, s
832833
if not isinstance(message.string, (list, tuple)):
833834
fuzzy = True
834835
message.string = tuple(
835-
[message.string] + ([u''] * (len(message.id) - 1))
836+
[message.string] + ([''] * (len(message.id) - 1))
836837
)
837838
elif len(message.string) != self.num_plurals:
838839
fuzzy = True
@@ -842,7 +843,7 @@ def _merge(message: Message, oldkey: tuple[str, str] | str, newkey: tuple[str, s
842843
message.string = message.string[0]
843844
message.flags |= oldmsg.flags
844845
if fuzzy:
845-
message.flags |= {u'fuzzy'}
846+
message.flags |= {'fuzzy'}
846847
self[message.id] = message
847848

848849
for message in template:

babel/messages/checkers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313

1414
from collections.abc import Callable
1515

16-
from babel.messages.catalog import Catalog, Message, TranslationError, PYTHON_FORMAT
17-
16+
from babel.messages.catalog import PYTHON_FORMAT, Catalog, Message, TranslationError
1817

1918
#: list of format chars that are compatible to each other
2019
_string_format_compatibilities = [
@@ -111,7 +110,7 @@ def _compatible(a: str, b: str) -> bool:
111110

112111
def _check_positional(results: list[tuple[str, str]]) -> bool:
113112
positional = None
114-
for name, char in results:
113+
for name, _char in results:
115114
if positional is None:
116115
positional = name is None
117116
else:

babel/messages/extract.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,29 @@
1818
from __future__ import annotations
1919

2020
import ast
21-
from collections.abc import Callable, Collection, Generator, Iterable, Mapping, MutableSequence
2221
import io
2322
import os
2423
import sys
24+
from collections.abc import (
25+
Callable,
26+
Collection,
27+
Generator,
28+
Iterable,
29+
Mapping,
30+
MutableSequence,
31+
)
2532
from os.path import relpath
26-
from tokenize import generate_tokens, COMMENT, NAME, OP, STRING
27-
from typing import Any, TYPE_CHECKING
33+
from textwrap import dedent
34+
from tokenize import COMMENT, NAME, OP, STRING, generate_tokens
35+
from typing import TYPE_CHECKING, Any
2836

2937
from babel.util import parse_encoding, parse_future_flags, pathmatch
30-
from textwrap import dedent
3138

3239
if TYPE_CHECKING:
3340
from typing import IO, Protocol
34-
from typing_extensions import Final, TypeAlias, TypedDict
41+
3542
from _typeshed import SupportsItems, SupportsRead, SupportsReadline
43+
from typing_extensions import Final, TypeAlias, TypedDict
3644

3745
class _PyOptions(TypedDict, total=False):
3846
encoding: str
@@ -82,7 +90,6 @@ def tell(self) -> int: ...
8290
DEFAULT_MAPPING: list[tuple[str, str]] = [('**.py', 'python')]
8391

8492

85-
8693
def _strip_comment_tags(comments: MutableSequence[str], tags: Iterable[str]):
8794
"""Helper function for `extract` that strips comment tags from strings
8895
in a list of comment lines. This functions operates in-place.
@@ -652,8 +659,7 @@ def extract_javascript(
652659
token = Token('operator', ')', token.lineno)
653660

654661
if options.get('parse_template_string') and not funcname and token.type == 'template_string':
655-
for item in parse_template_string(token.value, keywords, comment_tags, options, token.lineno):
656-
yield item
662+
yield from parse_template_string(token.value, keywords, comment_tags, options, token.lineno)
657663

658664
elif token.type == 'operator' and token.value == '(':
659665
if funcname:
@@ -786,8 +792,7 @@ def parse_template_string(
786792
if level == 0 and expression_contents:
787793
expression_contents = expression_contents[0:-1]
788794
fake_file_obj = io.BytesIO(expression_contents.encode())
789-
for item in extract_javascript(fake_file_obj, keywords, comment_tags, options, lineno):
790-
yield item
795+
yield from extract_javascript(fake_file_obj, keywords, comment_tags, options, lineno)
791796
lineno += len(line_re.findall(expression_contents))
792797
expression_contents = ''
793798
prev_character = character

0 commit comments

Comments
 (0)