Skip to content

Commit

Permalink
Rework infrastructure for linting
Browse files Browse the repository at this point in the history
Run mypy checks outside of `pre-commit` for completeness, and move to
Ruff for style checks.
  • Loading branch information
pradyunsg committed Sep 9, 2023
1 parent 5abeb9f commit 9cfdf44
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 36 deletions.
3 changes: 0 additions & 3 deletions .flake8

This file was deleted.

16 changes: 5 additions & 11 deletions .pre-commit-config.yaml
Expand Up @@ -34,18 +34,12 @@ repos:
- id: forbid-new-submodules
- id: trailing-whitespace

- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.0.287
hooks:
- id: flake8

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: mypy
args: [--disallow-untyped-defs, --ignore-missing-imports]
files: src/.*\.py$
additional_dependencies: [types-docutils]
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/PyCQA/pydocstyle
rev: 6.3.0
Expand Down
14 changes: 14 additions & 0 deletions noxfile.py
Expand Up @@ -84,6 +84,12 @@ def docs_live(session):

@nox.session(reuse_venv=True)
def lint(session):
session.notify("lint-pre-commit")
session.notify("lint-mypy")


@nox.session(reuse_venv=True, name="lint-pre-commit")
def lint_pre_commit(session):
session.install("pre-commit")

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


@nox.session(reuse_venv=True, name="lint-mypy")
def lint_mypy(session):
session.install(
"-e", ".", "mypy", "types-docutils", "types-Pygments", "types-beautifulsoup4"
)
session.run("mypy", "src")


@nox.session
def test(session):
session.install("-e", ".", "-r", "tests/requirements.txt")
Expand Down
18 changes: 10 additions & 8 deletions pyproject.toml
Expand Up @@ -4,9 +4,7 @@ build-backend = "sphinx_theme_builder"

[tool.sphinx-theme-builder]
node-version = "18.16.0"
additional-compiled-static-assets = [
"styles/furo-extensions.css",
]
additional-compiled-static-assets = ["styles/furo-extensions.css"]

[project]
name = "furo"
Expand All @@ -22,10 +20,8 @@ dependencies = [
"pygments >= 2.7",
]

license = { file = "LICENSE"}
authors = [
{name = "Pradyun Gedam", email = "mail@pradyunsg.me"},
]
license = { file = "LICENSE" }
authors = [{ name = "Pradyun Gedam", email = "mail@pradyunsg.me" }]
classifiers = [
"Framework :: Sphinx",
"Framework :: Sphinx :: Theme",
Expand All @@ -45,7 +41,13 @@ classifiers = [
]

[project.entry-points]
"sphinx.html_themes" = {furo = "furo"}
"sphinx.html_themes" = { furo = "furo" }

[project.urls]
GitHub = "https://github.com/pradyunsg/furo"

[tool.mypy]
strict = true

[tool.ruff]
ignore = ["E501"]
37 changes: 24 additions & 13 deletions src/furo/__init__.py
Expand Up @@ -7,7 +7,7 @@
import os
from functools import lru_cache
from pathlib import Path
from typing import Any, Dict, Iterator, List, Optional
from typing import Any, Dict, Iterator, List, Optional, cast

import sphinx.application
from docutils import nodes
Expand Down Expand Up @@ -71,7 +71,7 @@ def has_not_enough_items_to_show_toc(

toctree = TocTree(builder.env).get_toc_for(docname, builder)
try:
self_toctree = toctree[0][1]
self_toctree = toctree[0][1] # type: ignore[index]
except IndexError:
val = True
else:
Expand All @@ -84,8 +84,8 @@ def get_pygments_style_colors(
style: Style, *, fallbacks: Dict[str, str]
) -> Dict[str, str]:
"""Get background/foreground colors for given pygments style."""
background = style.background_color
text_colors = style.style_for_token(Text)
background = style.background_color # type: ignore[attr-defined]
text_colors = style.style_for_token(Text) # type: ignore[attr-defined]
foreground = text_colors["color"]

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

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


def _html_page_context(
Expand All @@ -201,9 +202,11 @@ def _html_page_context(
# Values computed from page-level context.
context["furo_navigation_tree"] = _compute_navigation_tree(context)
context["furo_hide_toc"] = _compute_hide_toc(
context, builder=app.builder, docname=pagename
context, builder=cast(StandaloneHTMLBuilder, app.builder), docname=pagename
)

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

builder = app.builder
assert (
builder.highlighter is not None
builder.highlighter is not None # type: ignore[attr-defined]
), "there should be a default style known to Sphinx"
assert (
builder.dark_highlighter is None
builder.dark_highlighter is None # type: ignore[attr-defined]
), "this shouldn't be a dark style known to Sphinx"
update_known_styles_state(app)

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


def _get_light_style(app: sphinx.application.Sphinx) -> Style:
return app.builder.highlighter.formatter_args["style"]
# fmt: off
# For https://github.com/psf/black/issues/3869
return (
app # type: ignore[no-any-return]
.builder
.highlighter # type: ignore[attr-defined]
.formatter_args["style"]
)
# fmt: on


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


def _get_styles(formatter: HtmlFormatter, *, prefix: str) -> Iterator[str]:
def _get_styles(formatter: HtmlFormatter[str], *, prefix: str) -> Iterator[str]:
"""Get styles out of a formatter, where everything has the correct prefix."""
for line in formatter.get_linenos_style_defs():
for line in formatter.get_linenos_style_defs(): # type: ignore[no-untyped-call]
yield f"{prefix} {line}"
yield from formatter.get_background_style_defs(prefix)
yield from formatter.get_token_style_defs(prefix)
Expand Down
2 changes: 1 addition & 1 deletion src/furo/sphinxext.py
Expand Up @@ -20,7 +20,7 @@
from docutils import nodes
from docutils.statemachine import StringList
from sphinx.application import Sphinx
from sphinx.directives import SphinxDirective
from sphinx.directives import SphinxDirective # type: ignore[attr-defined]


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

0 comments on commit 9cfdf44

Please sign in to comment.