Skip to content

Commit d51bb2b

Browse files
committed
Adopt Ruff and use stricter MyPy settings
1 parent fbc12da commit d51bb2b

File tree

10 files changed

+141
-49
lines changed

10 files changed

+141
-49
lines changed

.flake8

-4
This file was deleted.

.github/workflows/test.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ jobs:
7171
runs-on: ubuntu-latest
7272
strategy:
7373
matrix:
74-
env: [flake8, mypy]
74+
env:
75+
- ruff
76+
- mypy
7577

7678
steps:
7779
- uses: actions/checkout@v3

.ruff.toml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
target-version = "py39" # Pin Ruff to Python 3.9
2+
output-format = "full"
3+
line-length = 95
4+
5+
[lint]
6+
preview = true
7+
select = [
8+
# "ANN", # flake8-annotations
9+
"C4", # flake8-comprehensions
10+
"COM", # flake8-commas
11+
"B", # flake8-bugbear
12+
"DTZ", # flake8-datetimez
13+
"E", # pycodestyle
14+
"EM", # flake8-errmsg
15+
"EXE", # flake8-executable
16+
"F", # pyflakes
17+
"FA", # flake8-future-annotations
18+
"FLY", # flynt
19+
"FURB", # refurb
20+
"G", # flake8-logging-format
21+
"I", # isort
22+
"ICN", # flake8-import-conventions
23+
"INT", # flake8-gettext
24+
"LOG", # flake8-logging
25+
"PERF", # perflint
26+
"PGH", # pygrep-hooks
27+
"PIE", # flake8-pie
28+
"PT", # flake8-pytest-style
29+
"SIM", # flake8-simplify
30+
"SLOT", # flake8-slots
31+
"TCH", # flake8-type-checking
32+
"UP", # pyupgrade
33+
"W", # pycodestyle
34+
"YTT", # flake8-2020
35+
]
36+
ignore = [
37+
"E116",
38+
"E241",
39+
"E251",
40+
]
41+
42+
[lint.per-file-ignores]
43+
"tests/*" = [
44+
"ANN", # tests don't need annotations
45+
]
46+
47+
[lint.isort]
48+
forced-separate = [
49+
"tests",
50+
]
51+
required-imports = [
52+
"from __future__ import annotations",
53+
]

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ clean-mypyfiles:
4747

4848
.PHONY: style-check
4949
style-check:
50-
@flake8
50+
@ruff check
5151

5252
.PHONY: type-check
5353
type-check:

pyproject.toml

+33-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ test = [
4747
"pytest",
4848
]
4949
lint = [
50-
"flake8",
50+
"ruff==0.5.5",
5151
"mypy",
52-
"docutils-stubs",
52+
"types-docutils",
5353
]
5454
standalone = [
5555
"Sphinx>=5",
@@ -75,4 +75,34 @@ exclude = [
7575
]
7676

7777
[tool.mypy]
78-
ignore_missing_imports = true
78+
python_version = "3.9"
79+
packages = [
80+
"sphinxcontrib",
81+
"tests",
82+
]
83+
exclude = [
84+
"tests/roots",
85+
]
86+
check_untyped_defs = true
87+
disallow_any_generics = true
88+
disallow_incomplete_defs = true
89+
disallow_subclassing_any = true
90+
disallow_untyped_calls = true
91+
disallow_untyped_decorators = true
92+
disallow_untyped_defs = true
93+
explicit_package_bases = true
94+
extra_checks = true
95+
no_implicit_reexport = true
96+
show_column_numbers = true
97+
show_error_context = true
98+
strict_optional = true
99+
warn_redundant_casts = true
100+
warn_unused_configs = true
101+
warn_unused_ignores = true
102+
enable_error_code = [
103+
"type-arg",
104+
"redundant-self",
105+
"truthy-iterable",
106+
"ignore-without-code",
107+
"unused-awaitable",
108+
]

sphinxcontrib/applehelp/__init__.py

+34-24
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
"""Build Apple help books."""
22

3+
from __future__ import annotations
4+
35
import plistlib
46
import shlex
57
import subprocess
6-
from os import environ
7-
from os import path
8-
from subprocess import CalledProcessError, PIPE, STDOUT
9-
from typing import Any
8+
from os import environ, path
9+
from pathlib import Path
10+
from subprocess import PIPE, STDOUT, CalledProcessError
11+
from typing import TYPE_CHECKING
1012

1113
import sphinx
12-
from sphinx.application import Sphinx
1314
from sphinx.builders.html import StandaloneHTMLBuilder
1415
from sphinx.errors import SphinxError
1516
from sphinx.locale import get_translation
@@ -18,11 +19,17 @@
1819
from sphinx.util.matching import Matcher
1920
from sphinx.util.osutil import ensuredir, make_filename
2021

22+
if TYPE_CHECKING:
23+
from typing import Any
24+
25+
from sphinx.application import Sphinx
26+
2127
if sphinx.version_info[:2] >= (6, 1):
2228
from sphinx.util.display import SkipProgressMessage, progress_message
2329
else:
24-
from sphinx.util import ( # type: ignore[attr-defined,no-redef]
25-
SkipProgressMessage, progress_message
30+
from sphinx.util import ( # type: ignore[no-redef]
31+
SkipProgressMessage,
32+
progress_message,
2633
)
2734

2835
__version__ = '1.0.8'
@@ -75,16 +82,17 @@ def init(self) -> None:
7582
self.link_suffix = '.html'
7683

7784
if self.config.applehelp_bundle_id is None:
78-
raise SphinxError(__('You must set applehelp_bundle_id before '
79-
'building Apple Help output'))
85+
msg = __('You must set applehelp_bundle_id '
86+
'before building Apple Help output')
87+
raise SphinxError(msg)
8088

8189
self.bundle_path = path.join(self.outdir, self.config.applehelp_bundle_name + '.help')
82-
self.outdir = path.join( # type: ignore[assignment]
90+
self.outdir = type(self.outdir)(Path(
8391
self.bundle_path,
8492
'Contents',
8593
'Resources',
8694
self.config.applehelp_locale + '.lproj',
87-
)
95+
))
8896

8997
def handle_finish(self) -> None:
9098
super().handle_finish()
@@ -94,7 +102,7 @@ def handle_finish(self) -> None:
94102

95103
@progress_message(__('copying localized files'))
96104
def copy_localized_files(self) -> None:
97-
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj') # type: ignore # NOQA
105+
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
98106
target_dir = self.outdir
99107

100108
if path.isdir(source_dir):
@@ -175,14 +183,14 @@ def build_helpindex(self, language_dir: str) -> None:
175183
self.config.applehelp_indexer_path,
176184
'-Cf',
177185
path.join(language_dir, 'search.helpindex'),
178-
language_dir
186+
language_dir,
179187
]
180188

181189
if self.config.applehelp_index_anchors is not None:
182190
args.append('-a')
183191

184192
if self.config.applehelp_min_term_length is not None:
185-
args += ['-m', '%s' % self.config.applehelp_min_term_length]
193+
args += ['-m', f'{self.config.applehelp_min_term_length}']
186194

187195
if self.config.applehelp_stopwords is not None:
188196
args += ['-s', self.config.applehelp_stopwords]
@@ -196,18 +204,19 @@ def build_helpindex(self, language_dir: str) -> None:
196204
else:
197205
try:
198206
subprocess.run(args, stdout=PIPE, stderr=STDOUT, check=True)
199-
except OSError:
200-
raise AppleHelpIndexerFailed(__('Command not found: %s') % args[0])
201-
except CalledProcessError as exc:
202-
raise AppleHelpIndexerFailed(exc.stdout)
207+
except OSError as err:
208+
msg = __('Command not found: %s') % args[0]
209+
raise AppleHelpIndexerFailed(msg) from err
210+
except CalledProcessError as err:
211+
raise AppleHelpIndexerFailed(err.stdout) from err
203212

204213
@progress_message(__('signing help book'))
205214
def do_codesign(self) -> None:
206215
"""If we've been asked to, sign the bundle."""
207216
args = [
208217
self.config.applehelp_codesign_path,
209218
'-s', self.config.applehelp_codesign_identity,
210-
'-f'
219+
'-f',
211220
]
212221

213222
args += self.config.applehelp_codesign_flags
@@ -220,10 +229,11 @@ def do_codesign(self) -> None:
220229
else:
221230
try:
222231
subprocess.run(args, stdout=PIPE, stderr=STDOUT, check=True)
223-
except OSError:
224-
raise AppleHelpCodeSigningFailed(__('Command not found: %s') % args[0])
225-
except CalledProcessError as exc:
226-
raise AppleHelpCodeSigningFailed(exc.stdout)
232+
except OSError as err:
233+
msg = __('Command not found: %s') % args[0]
234+
raise AppleHelpCodeSigningFailed(msg) from err
235+
except CalledProcessError as err:
236+
raise AppleHelpCodeSigningFailed(err.stdout) from err
227237

228238

229239
def setup(app: Sphinx) -> dict[str, Any]:
@@ -239,7 +249,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
239249
app.add_config_value('applehelp_bundle_version', '1', 'applehelp')
240250
app.add_config_value('applehelp_icon', None, 'applehelp', [str])
241251
app.add_config_value('applehelp_kb_product',
242-
lambda self: '%s-%s' % (make_filename(self.project), self.release),
252+
lambda self: f'{make_filename(self.project)}-{self.release}',
243253
'applehelp')
244254
app.add_config_value('applehelp_kb_url', None, 'applehelp', [str])
245255
app.add_config_value('applehelp_remote_url', None, 'applehelp', [str])

sphinxcontrib/applehelp/py.typed

Whitespace-only changes.

tests/conftest.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1+
from __future__ import annotations
2+
13
from pathlib import Path
24

35
import pytest
46

5-
import sphinx
6-
77
pytest_plugins = 'sphinx.testing.fixtures'
88

99

1010
@pytest.fixture(scope='session')
11-
def rootdir():
12-
if sphinx.version_info[:2] < (7, 2):
13-
from sphinx.testing.path import path
14-
15-
return path(__file__).parent.abspath() / 'roots'
16-
11+
def rootdir() -> Path:
1712
return Path(__file__).resolve().parent / 'roots'

tests/test_applehelp.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""Test for applehelp extension."""
22

3-
from pathlib import Path
3+
from __future__ import annotations
4+
45
import plistlib
6+
from pathlib import Path
7+
from typing import TYPE_CHECKING
58

69
import pytest
710

11+
if TYPE_CHECKING:
12+
from sphinx.application import Sphinx
13+
814

9-
def check_structure(outdir):
15+
def check_structure(outdir: Path) -> None:
1016
contentsdir = outdir / 'Contents'
1117
assert contentsdir.is_dir()
1218
assert (contentsdir / 'Info.plist').is_file()
@@ -21,7 +27,7 @@ def check_structure(outdir):
2127
assert (contentsdir / 'Resources' / 'en.lproj').is_dir()
2228

2329

24-
def check_localization(outdir):
30+
def check_localization(outdir: Path) -> None:
2531
lprojdir = outdir / 'Contents' / 'Resources' / 'en.lproj'
2632
assert (lprojdir / 'localized.txt').is_file()
2733

@@ -30,7 +36,7 @@ def check_localization(outdir):
3036
'applehelp', testroot='basic', srcdir='applehelp_output',
3137
confoverrides={'applehelp_bundle_id': 'org.sphinx-doc.Sphinx.help',
3238
'applehelp_disable_external_tools': True})
33-
def test_applehelp_output(app, status, warning):
39+
def test_applehelp_output(app: Sphinx) -> None:
3440
LPROJ_DIR = Path(app.srcdir / 'en.lproj')
3541
LPROJ_DIR.mkdir(parents=True, exist_ok=True)
3642
LPROJ_DIR.joinpath('localized.txt').touch()
@@ -39,6 +45,6 @@ def test_applehelp_output(app, status, warning):
3945
# Have to use bundle_path, not outdir, because we alter the latter
4046
# to point to the lproj directory so that the HTML arrives in the
4147
# correct location.
42-
bundle_path = Path(app.builder.bundle_path)
48+
bundle_path = Path(app.builder.bundle_path) # type: ignore[attr-defined]
4349
check_structure(bundle_path)
4450
check_localization(bundle_path)

tox.ini

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
minversion = 2.4.0
33
envlist =
44
py{39,310,311,312,313},
5-
flake8,
5+
ruff,
66
mypy
77
isolated_build = True
88

@@ -28,13 +28,13 @@ setenv =
2828
commands=
2929
python -X dev -X warn_default_encoding -m pytest --durations 25 {posargs}
3030

31-
[testenv:flake8]
31+
[testenv:ruff]
3232
description =
3333
Run style checks.
3434
extras=
3535
lint
3636
commands=
37-
flake8
37+
ruff check
3838

3939
[testenv:mypy]
4040
description =

0 commit comments

Comments
 (0)