Skip to content

Commit 9cfdf44

Browse files
committed
Rework infrastructure for linting
Run mypy checks outside of `pre-commit` for completeness, and move to Ruff for style checks.
1 parent 5abeb9f commit 9cfdf44

File tree

6 files changed

+54
-36
lines changed

6 files changed

+54
-36
lines changed

.flake8

-3
This file was deleted.

.pre-commit-config.yaml

+5-11
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,12 @@ repos:
3434
- id: forbid-new-submodules
3535
- id: trailing-whitespace
3636

37-
- repo: https://github.com/PyCQA/flake8
38-
rev: 6.1.0
37+
- repo: https://github.com/astral-sh/ruff-pre-commit
38+
# Ruff version.
39+
rev: v0.0.287
3940
hooks:
40-
- id: flake8
41-
42-
- repo: https://github.com/pre-commit/mirrors-mypy
43-
rev: v1.4.1
44-
hooks:
45-
- id: mypy
46-
args: [--disallow-untyped-defs, --ignore-missing-imports]
47-
files: src/.*\.py$
48-
additional_dependencies: [types-docutils]
41+
- id: ruff
42+
args: [--fix, --exit-non-zero-on-fix]
4943

5044
- repo: https://github.com/PyCQA/pydocstyle
5145
rev: 6.3.0

noxfile.py

+14
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ def docs_live(session):
8484

8585
@nox.session(reuse_venv=True)
8686
def lint(session):
87+
session.notify("lint-pre-commit")
88+
session.notify("lint-mypy")
89+
90+
91+
@nox.session(reuse_venv=True, name="lint-pre-commit")
92+
def lint_pre_commit(session):
8793
session.install("pre-commit")
8894

8995
args = list(session.posargs)
@@ -94,6 +100,14 @@ def lint(session):
94100
session.run("pre-commit", "run", *args)
95101

96102

103+
@nox.session(reuse_venv=True, name="lint-mypy")
104+
def lint_mypy(session):
105+
session.install(
106+
"-e", ".", "mypy", "types-docutils", "types-Pygments", "types-beautifulsoup4"
107+
)
108+
session.run("mypy", "src")
109+
110+
97111
@nox.session
98112
def test(session):
99113
session.install("-e", ".", "-r", "tests/requirements.txt")

pyproject.toml

+10-8
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ build-backend = "sphinx_theme_builder"
44

55
[tool.sphinx-theme-builder]
66
node-version = "18.16.0"
7-
additional-compiled-static-assets = [
8-
"styles/furo-extensions.css",
9-
]
7+
additional-compiled-static-assets = ["styles/furo-extensions.css"]
108

119
[project]
1210
name = "furo"
@@ -22,10 +20,8 @@ dependencies = [
2220
"pygments >= 2.7",
2321
]
2422

25-
license = { file = "LICENSE"}
26-
authors = [
27-
{name = "Pradyun Gedam", email = "mail@pradyunsg.me"},
28-
]
23+
license = { file = "LICENSE" }
24+
authors = [{ name = "Pradyun Gedam", email = "mail@pradyunsg.me" }]
2925
classifiers = [
3026
"Framework :: Sphinx",
3127
"Framework :: Sphinx :: Theme",
@@ -45,7 +41,13 @@ classifiers = [
4541
]
4642

4743
[project.entry-points]
48-
"sphinx.html_themes" = {furo = "furo"}
44+
"sphinx.html_themes" = { furo = "furo" }
4945

5046
[project.urls]
5147
GitHub = "https://github.com/pradyunsg/furo"
48+
49+
[tool.mypy]
50+
strict = true
51+
52+
[tool.ruff]
53+
ignore = ["E501"]

src/furo/__init__.py

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88
from functools import lru_cache
99
from pathlib import Path
10-
from typing import Any, Dict, Iterator, List, Optional
10+
from typing import Any, Dict, Iterator, List, Optional, cast
1111

1212
import sphinx.application
1313
from docutils import nodes
@@ -71,7 +71,7 @@ def has_not_enough_items_to_show_toc(
7171

7272
toctree = TocTree(builder.env).get_toc_for(docname, builder)
7373
try:
74-
self_toctree = toctree[0][1]
74+
self_toctree = toctree[0][1] # type: ignore[index]
7575
except IndexError:
7676
val = True
7777
else:
@@ -84,8 +84,8 @@ def get_pygments_style_colors(
8484
style: Style, *, fallbacks: Dict[str, str]
8585
) -> Dict[str, str]:
8686
"""Get background/foreground colors for given pygments style."""
87-
background = style.background_color
88-
text_colors = style.style_for_token(Text)
87+
background = style.background_color # type: ignore[attr-defined]
88+
text_colors = style.style_for_token(Text) # type: ignore[attr-defined]
8989
foreground = text_colors["color"]
9090

9191
if not background:
@@ -172,9 +172,10 @@ def _add_asset_hashes(static: List[str], add_digest_to: List[str]) -> None:
172172
"theme-provide assets such as `html_style`."
173173
)
174174

175-
if "?digest=" in static[index].filename: # make this idempotent
175+
# Make this idempotent
176+
if "?digest=" in static[index].filename: # type: ignore[attr-defined]
176177
continue
177-
static[index].filename = _asset_hash(asset) # type: ignore
178+
static[index].filename = _asset_hash(asset) # type: ignore[attr-defined]
178179

179180

180181
def _html_page_context(
@@ -201,9 +202,11 @@ def _html_page_context(
201202
# Values computed from page-level context.
202203
context["furo_navigation_tree"] = _compute_navigation_tree(context)
203204
context["furo_hide_toc"] = _compute_hide_toc(
204-
context, builder=app.builder, docname=pagename
205+
context, builder=cast(StandaloneHTMLBuilder, app.builder), docname=pagename
205206
)
206207

208+
assert _KNOWN_STYLES_IN_USE["light"]
209+
assert _KNOWN_STYLES_IN_USE["dark"]
207210
# Inject information about styles
208211
context["furo_pygments"] = {
209212
"light": get_pygments_style_colors(
@@ -248,10 +251,10 @@ def _builder_inited(app: sphinx.application.Sphinx) -> None:
248251

249252
builder = app.builder
250253
assert (
251-
builder.highlighter is not None
254+
builder.highlighter is not None # type: ignore[attr-defined]
252255
), "there should be a default style known to Sphinx"
253256
assert (
254-
builder.dark_highlighter is None
257+
builder.dark_highlighter is None # type: ignore[attr-defined]
255258
), "this shouldn't be a dark style known to Sphinx"
256259
update_known_styles_state(app)
257260

@@ -273,17 +276,25 @@ def update_known_styles_state(app: sphinx.application.Sphinx) -> None:
273276

274277

275278
def _get_light_style(app: sphinx.application.Sphinx) -> Style:
276-
return app.builder.highlighter.formatter_args["style"]
279+
# fmt: off
280+
# For https://github.com/psf/black/issues/3869
281+
return (
282+
app # type: ignore[no-any-return]
283+
.builder
284+
.highlighter # type: ignore[attr-defined]
285+
.formatter_args["style"]
286+
)
287+
# fmt: on
277288

278289

279290
def _get_dark_style(app: sphinx.application.Sphinx) -> Style:
280291
dark_style = app.config.pygments_dark_style
281-
return PygmentsBridge("html", dark_style).formatter_args["style"]
292+
return cast(Style, PygmentsBridge("html", dark_style).formatter_args["style"])
282293

283294

284-
def _get_styles(formatter: HtmlFormatter, *, prefix: str) -> Iterator[str]:
295+
def _get_styles(formatter: HtmlFormatter[str], *, prefix: str) -> Iterator[str]:
285296
"""Get styles out of a formatter, where everything has the correct prefix."""
286-
for line in formatter.get_linenos_style_defs():
297+
for line in formatter.get_linenos_style_defs(): # type: ignore[no-untyped-call]
287298
yield f"{prefix} {line}"
288299
yield from formatter.get_background_style_defs(prefix)
289300
yield from formatter.get_token_style_defs(prefix)

src/furo/sphinxext.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from docutils import nodes
2121
from docutils.statemachine import StringList
2222
from sphinx.application import Sphinx
23-
from sphinx.directives import SphinxDirective
23+
from sphinx.directives import SphinxDirective # type: ignore[attr-defined]
2424

2525

2626
def _split_by_language(block_text: str) -> Tuple[str, str]:

0 commit comments

Comments
 (0)