Skip to content

Commit 2a7a5ee

Browse files
authored
Replace black and flake8 with ruff (#182)
1 parent 3f46d16 commit 2a7a5ee

File tree

11 files changed

+143
-123
lines changed

11 files changed

+143
-123
lines changed

.flake8

Lines changed: 0 additions & 8 deletions
This file was deleted.

.pre-commit-config.yaml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@ repos:
2222
rev: 1.5.0
2323
hooks:
2424
- id: tox-ini-fmt
25-
26-
- repo: https://github.com/psf/black
27-
rev: 25.1.0
28-
hooks:
29-
- id: black
30-
- repo: https://github.com/pycqa/flake8
31-
rev: 7.2.0
25+
- repo: https://github.com/astral-sh/ruff-pre-commit
26+
rev: v0.11.12
3227
hooks:
33-
- id: flake8
28+
- id: ruff-format
29+
alias: ruff
30+
- id: ruff-check
31+
alias: ruff
3432
- repo: https://github.com/pre-commit/mirrors-mypy
3533
rev: v1.16.0
3634
hooks:

MANIFEST.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ recursive-include docs *.ico
1515
recursive-include docs *.png
1616
recursive-include docs *.py
1717
recursive-include docs *.rst
18-
recursive-include src *.flake8
1918
recursive-include src *.j2
2019
recursive-include src *.json
2120
recursive-include src *.md

pyproject.toml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ py-version = "3.10.0"
9898

9999
[tool.pylint."MESSAGES CONTROL"]
100100
disable = [
101+
"line-too-long",
101102
# TODO(ssbarnea): remove temporary skips adding during initial adoption:
102103
"attribute-defined-outside-init",
103104
"consider-using-f-string",
@@ -126,6 +127,66 @@ filterwarnings = [
126127
"ignore:The frontend.*:DeprecationWarning"
127128
]
128129

130+
[tool.ruff]
131+
fix = true
132+
# Same as Black.
133+
line-length = 88
134+
preview = true
135+
target-version = "py310"
136+
137+
[tool.ruff.lint]
138+
ignore = [
139+
"E501",
140+
# temporary disabled until we fix them:
141+
"A001",
142+
"ANN",
143+
"B007",
144+
"BLE001",
145+
"C410",
146+
"C419",
147+
"C901",
148+
"CPY001",
149+
"D",
150+
"DOC",
151+
"EM102",
152+
"ERA001",
153+
"FBT002",
154+
"FBT003",
155+
"FLY002",
156+
"FURB101",
157+
"FURB103",
158+
"INP001",
159+
"PERF401",
160+
"PGH003",
161+
"PGH004",
162+
"PLR0912",
163+
"PLR0915",
164+
"PLR1702",
165+
"PLR6104",
166+
"PLR6301",
167+
"PLW2901",
168+
"PT009",
169+
"PTH",
170+
"RUF012",
171+
"RUF059",
172+
"S108",
173+
"SIM102",
174+
"SIM103",
175+
"SIM105",
176+
"SIM108",
177+
"SLF001",
178+
"T201",
179+
"TRY003",
180+
"UP031"
181+
]
182+
select = ["ALL"]
183+
184+
[tool.ruff.lint.isort]
185+
known-first-party = ["src"]
186+
187+
[tool.ruff.lint.pydocstyle]
188+
convention = "google"
189+
129190
[tool.setuptools]
130191
include-package-data = true
131192
# These are required in actual runtime:

src/doc8/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""doc8 - A docutils linter."""
22

33
from __future__ import annotations
4-
from doc8.version import __version__
5-
from doc8.main import doc8 # noqa
64

5+
from doc8.main import doc8 # noqa
6+
from doc8.version import __version__
77

88
__all__ = ("__version__",)

src/doc8/__main__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,4 @@
1616

1717
from doc8 import main
1818

19-
2019
sys.exit(main.main())

src/doc8/checks.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from doc8 import utils
2222

2323

24-
class ContentCheck(metaclass=abc.ABCMeta):
24+
class ContentCheck(abc.ABC):
2525
def __init__(self, cfg):
2626
self._cfg = cfg
2727

@@ -30,7 +30,7 @@ def report_iter(self, parsed_file):
3030
pass
3131

3232

33-
class LineCheck(metaclass=abc.ABCMeta):
33+
class LineCheck(abc.ABC):
3434
def __init__(self, cfg):
3535
self._cfg = cfg
3636

@@ -83,7 +83,7 @@ def report_iter(self, parsed_file):
8383

8484
class CheckValidity(ContentCheck):
8585
REPORTS = frozenset(["D000"])
86-
EXT_MATCHER = re.compile(r"(.*)[.]rst", re.I)
86+
EXT_MATCHER = re.compile(r"(.*)[.]rst", re.IGNORECASE)
8787

8888
# From docutils docs:
8989
#
@@ -104,11 +104,11 @@ class CheckValidity(ContentCheck):
104104
re.MULTILINE,
105105
),
106106
re.compile(
107-
r'^Error in "code-block" directive:\nunknown option: "emphasize-lines"'
107+
r'^Error in "code-block" directive:\nunknown option: "emphasize-lines"',
108108
),
109109
re.compile(r'^Error in "code-block" directive:\nunknown option: "linenos"'),
110110
re.compile(
111-
r'^Error in "code-block" directive:\nunknown option: "lineno-start"'
111+
r'^Error in "code-block" directive:\nunknown option: "lineno-start"',
112112
),
113113
re.compile(r'^Error in "code-block" directive:\nunknown option: "dedent"'),
114114
re.compile(r'^Error in "code-block" directive:\nunknown option: "force"'),
@@ -119,7 +119,7 @@ class CheckValidity(ContentCheck):
119119
re.MULTILINE,
120120
),
121121
re.compile(
122-
r'^PEP number must be a number from 0 to 9999; "\d{1,4}#[^"]*" is invalid.'
122+
r'^PEP number must be a number from 0 to 9999; "\d{1,4}#[^"]*" is invalid.',
123123
),
124124
]
125125

@@ -218,16 +218,14 @@ def find_directive_end(start, lines):
218218
# for unknown directives, so we have to do it manually).
219219
directives = []
220220
for i, line in enumerate(lines):
221-
if re.match(r"^\s*..\s(.*?)::\s*", line):
222-
directives.append((i, find_directive_end(i, lines)))
223-
elif re.match(r"^::\s*$", line):
221+
if re.match(r"^\s*..\s(.*?)::\s*", line) or re.match(r"^::\s*$", line):
224222
directives.append((i, find_directive_end(i, lines)))
225223

226224
# Find definition terms in definition lists
227225
# This check may match the code, which is already appended
228226
lwhitespaces = r"^\s*"
229227
listspattern = r"^\s*(\* |- |#\. |\d+\. )"
230-
for i in range(0, len(lines) - 1):
228+
for i in range(len(lines) - 1):
231229
line = lines[i]
232230
next_line = lines[i + 1]
233231
# if line is a blank, line is not a definition term
@@ -237,7 +235,7 @@ def find_directive_end(start, lines):
237235
if re.match(listspattern, line):
238236
continue
239237
if len(re.search(lwhitespaces, line).group()) < len(
240-
re.search(lwhitespaces, next_line).group()
238+
re.search(lwhitespaces, next_line).group(),
241239
):
242240
directives.append((i, i))
243241

@@ -266,10 +264,7 @@ def find_containing_nodes(num):
266264
best_nodes = []
267265
for n, (line_min, line_max) in contained_in:
268266
span = line_max - line_min
269-
if smallest_span is None:
270-
smallest_span = span
271-
best_nodes = [n]
272-
elif span < smallest_span:
267+
if smallest_span is None or span < smallest_span:
273268
smallest_span = span
274269
best_nodes = [n]
275270
elif span == smallest_span:

src/doc8/main.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import os
3636
import sys
3737

38-
3938
try:
4039
# py3.11+
4140
from tomllib import load as toml_load # type: ignore
@@ -45,10 +44,8 @@
4544

4645
from stevedore import extension
4746

48-
from doc8 import checks
47+
from doc8 import checks, utils, version
4948
from doc8 import parser as file_parser
50-
from doc8 import utils
51-
from doc8 import version
5249

5350
FILE_PATTERNS = [".rst", ".txt"]
5451
MAX_LINE_LENGTH = 79
@@ -158,7 +155,8 @@ def extract_config(args):
158155
if not os.path.isfile(cfg_file):
159156
if args["config"]:
160157
print(
161-
"Configuration file %s does not exist...ignoring" % (args["config"])
158+
"Configuration file %s does not exist...ignoring"
159+
% (args["config"]),
162160
)
163161
continue
164162
if cfg_file.endswith((".ini", ".cfg")):
@@ -180,7 +178,9 @@ def fetch_checks(cfg):
180178
checks.CheckNewlineEndOfFile(cfg),
181179
]
182180
mgr = extension.ExtensionManager(
183-
namespace="doc8.extension.check", invoke_on_load=True, invoke_args=(cfg.copy(),)
181+
namespace="doc8.extension.check",
182+
invoke_on_load=True,
183+
invoke_args=(cfg.copy(),),
184184
)
185185
addons = []
186186
for e in mgr:
@@ -194,7 +194,9 @@ def setup_logging(verbose):
194194
else:
195195
level = logging.ERROR
196196
logging.basicConfig(
197-
level=level, format="%(levelname)s: %(message)s", stream=sys.stdout
197+
level=level,
198+
format="%(levelname)s: %(message)s",
199+
stream=sys.stdout,
198200
)
199201

200202

@@ -205,7 +207,9 @@ def scan(cfg):
205207
ignored_paths = cfg.get("ignore_path", [])
206208
files_ignored = 0
207209
file_iter = utils.find_files(
208-
cfg.get("paths", []), cfg.get("extension", []), ignored_paths
210+
cfg.get("paths", []),
211+
cfg.get("extension", []),
212+
ignored_paths,
209213
)
210214
default_extension = cfg.get("default_extension")
211215
file_encoding = cfg.get("file_encoding")
@@ -216,7 +220,9 @@ def scan(cfg):
216220
print(" Ignoring '%s'" % (filename))
217221
else:
218222
f = file_parser.parse(
219-
filename, default_extension=default_extension, encoding=file_encoding
223+
filename,
224+
default_extension=default_extension,
225+
encoding=file_encoding,
220226
)
221227
files.append(f)
222228
if cfg.get("verbose"):
@@ -253,7 +259,7 @@ def validate(cfg, files, result=None):
253259
print(
254260
" Skipping check '%s' since it does not"
255261
" understand parsing a file with extension '%s'"
256-
% (check_name, f.extension)
262+
% (check_name, f.extension),
257263
)
258264
continue
259265
try:
@@ -266,7 +272,7 @@ def validate(cfg, files, result=None):
266272
if cfg.get("verbose"):
267273
print(
268274
" Skipping check '%s', determined to only"
269-
" check ignoreable codes" % check_name
275+
" check ignoreable codes" % check_name,
270276
)
271277
continue
272278
if cfg.get("verbose"):
@@ -279,13 +285,11 @@ def validate(cfg, files, result=None):
279285
line_num = "?"
280286
if cfg.get("verbose"):
281287
print(
282-
" - {}:{}: {} {}".format(
283-
f.filename, line_num, code, message
284-
)
288+
f" - {f.filename}:{line_num}: {code} {message}",
285289
)
286290
elif not result.capture:
287291
print(
288-
"{}:{}: {} {}".format(f.filename, line_num, code, message)
292+
f"{f.filename}:{line_num}: {code} {message}",
289293
)
290294
result.error(check_name, f.filename, line_num, code, message)
291295
error_counts[check_name] += 1
@@ -297,18 +301,16 @@ def validate(cfg, files, result=None):
297301
if cfg.get("verbose"):
298302
print(
299303
" - %s:%s: %s %s"
300-
% (f.filename, line_num, code, message)
304+
% (f.filename, line_num, code, message),
301305
)
302306
elif not result.capture:
303307
print(
304-
"{}:{}: {} {}".format(
305-
f.filename, line_num, code, message
306-
)
308+
f"{f.filename}:{line_num}: {code} {message}",
307309
)
308310
result.error(check_name, f.filename, line_num, code, message)
309311
error_counts[check_name] += 1
310312
else:
311-
raise TypeError("Unknown check type: {}, {}".format(type(c), c))
313+
raise TypeError(f"Unknown check type: {type(c)}, {c}")
312314
return error_counts
313315

314316

@@ -358,20 +360,18 @@ def report(self):
358360
for error in self.errors:
359361
lines.append("%s:%s: %s %s" % error[1:])
360362

361-
lines.extend(
362-
[
363-
"=" * 8,
364-
"Total files scanned = %s" % (self.files_selected),
365-
"Total files ignored = %s" % (self.files_ignored),
366-
"Total accumulated errors = %s" % (self.total_errors),
367-
]
368-
)
363+
lines.extend([
364+
"=" * 8,
365+
"Total files scanned = %s" % (self.files_selected),
366+
"Total files ignored = %s" % (self.files_ignored),
367+
"Total accumulated errors = %s" % (self.total_errors),
368+
])
369369

370370
if self.error_counts:
371371
lines.append("Detailed error counts:")
372372
for check_name in sorted(self.error_counts.keys()):
373373
check_errors = self.error_counts[check_name]
374-
lines.append(" - {} = {}".format(check_name, check_errors))
374+
lines.append(f" - {check_name} = {check_errors}")
375375

376376
return "\n".join(lines)
377377

0 commit comments

Comments
 (0)