Skip to content

Commit e1acce2

Browse files
authored
🔧 Move to ruff (#185)
1 parent 5ad542b commit e1acce2

16 files changed

+105
-84
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ jobs:
6060
if: matrix.python-version == '3.8' && matrix.os == 'ubuntu-latest'
6161
uses: codecov/codecov-action@v3
6262
with:
63+
token: ${{ secrets.CODECOV_TOKEN }}
6364
name: pytests
6465
flags: pytests
6566
file: ./coverage.xml

.pre-commit-config.yaml

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,22 @@ exclude: >
1111
repos:
1212

1313
- repo: https://github.com/pre-commit/pre-commit-hooks
14-
rev: v4.4.0
14+
rev: v4.6.0
1515
hooks:
1616
- id: check-json
1717
- id: check-yaml
1818
- id: end-of-file-fixer
1919
- id: trailing-whitespace
2020

21-
- repo: https://github.com/pycqa/isort
22-
rev: 5.12.0
21+
- repo: https://github.com/astral-sh/ruff-pre-commit
22+
rev: v0.4.4
2323
hooks:
24-
- id: isort
25-
26-
- repo: https://github.com/psf/black
27-
rev: 23.7.0
28-
hooks:
29-
- id: black
30-
31-
- repo: https://github.com/PyCQA/flake8
32-
rev: 6.1.0
33-
hooks:
34-
- id: flake8
35-
additional_dependencies: [flake8-bugbear~=22.7]
24+
- id: ruff
25+
args: [--fix]
26+
- id: ruff-format
3627

3728
- repo: https://github.com/pre-commit/mirrors-mypy
38-
rev: v1.5.1
29+
rev: v1.10.0
3930
hooks:
4031
- id: mypy
4132
additional_dependencies: []

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Configuration file for the Sphinx documentation builder."""
2+
23
import os
34

45
project = "Sphinx Design"

pyproject.toml

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ testing = [
4141
"pytest~=7.1",
4242
"pytest-cov",
4343
"pytest-regressions",
44+
"defusedxml",
4445
]
4546
theme_furo = ["furo~=2023.7.0"]
4647
theme_pydata = ["pydata-sphinx-theme~=0.13.0"]
@@ -54,6 +55,37 @@ exclude = [
5455
"tests/",
5556
]
5657

58+
[tool.ruff.lint]
59+
extend-select = [
60+
"B", # flake8-bugbear
61+
"C4", # flake8-comprehensions
62+
# "FURB",# refurb (modernising code)
63+
"I", # isort
64+
"ICN", # flake8-import-conventions
65+
"ISC", # flake8-implicit-str-concat
66+
"N", # pep8-naming
67+
"PERF",# perflint (performance anti-patterns)
68+
"PGH", # pygrep-hooks
69+
"PIE", # flake8-pie
70+
"PL", # pylint
71+
"PTH", # flake8-use-pathlib
72+
"RUF", # Ruff-specific rules
73+
"SIM", # flake8-simplify
74+
"UP", # pyupgrade
75+
"T20", # flake8-print
76+
]
77+
extend-ignore = [
78+
"ISC001", # implicit-str-concat
79+
"PLR2004",
80+
"RUF012",
81+
]
82+
83+
# [tool.ruff.lint.per-file-ignores]
84+
# "..." = ["N801"]
85+
86+
[tool.ruff.lint.isort]
87+
force-sort-within-sections = true
88+
5789
[tool.mypy]
5890
show_error_codes = true
5991
warn_unused_ignores = true
@@ -64,8 +96,3 @@ strict_equality = true
6496
[[tool.mypy.overrides]]
6597
module = ["docutils.*"]
6698
ignore_missing_imports = true
67-
68-
[tool.isort]
69-
profile = "black"
70-
src_paths = ["sphinx_design", "tests"]
71-
force_sort_within_sections = true

sphinx_design/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""A sphinx extension for designing beautiful, view size responsive web components."""
2+
23
from typing import TYPE_CHECKING
34

45
__version__ = "0.5.0"

sphinx_design/_compat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Helpers for cross compatibility across dependency versions."""
2+
23
from importlib import resources
34
from typing import Callable, Iterable
45

sphinx_design/article_info.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def _parse_text(
4848
output = [para]
4949
return output
5050

51-
def run(self) -> List[nodes.Node]:
51+
def run(self) -> List[nodes.Node]: # noqa: PLR0915
5252
"""Run the directive."""
5353
parse_fields = True # parse field text
5454

@@ -60,8 +60,8 @@ def run(self) -> List[nodes.Node]:
6060
"sd-p-0",
6161
"sd-mt-2",
6262
"sd-mb-4",
63-
]
64-
+ self.options.get("class-container", []),
63+
*self.options.get("class-container", []),
64+
],
6565
)
6666
self.set_source_info(top_grid)
6767

sphinx_design/cards.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def run(self) -> List[nodes.Node]:
7777
return [self.create_card(self, self.arguments, self.options)]
7878

7979
@classmethod
80-
def create_card(
80+
def create_card( # noqa: PLR0912, PLR0915
8181
cls, inst: SphinxDirective, arguments: Optional[list], options: dict
8282
) -> nodes.Node:
8383
"""Run the directive."""
@@ -118,7 +118,7 @@ def create_card(
118118
"",
119119
uri=options["img-top"],
120120
alt=img_alt,
121-
classes=["sd-card-img-top"] + options.get("class-img-top", []),
121+
classes=["sd-card-img-top", *options.get("class-img-top", [])],
122122
)
123123
container.append(image_top)
124124

@@ -137,8 +137,11 @@ def create_card(
137137
if arguments:
138138
title = create_component(
139139
"card-title",
140-
["sd-card-title", "sd-font-weight-bold"]
141-
+ options.get("class-title", []),
140+
[
141+
"sd-card-title",
142+
"sd-font-weight-bold",
143+
*options.get("class-title", []),
144+
],
142145
)
143146
textnodes, _ = inst.state.inline_text(arguments[0], inst.lineno)
144147
title_container = PassthroughTextElement()
@@ -160,7 +163,7 @@ def create_card(
160163
"",
161164
uri=options["img-bottom"],
162165
alt=img_alt,
163-
classes=["sd-card-img-bottom"] + options.get("class-img-bottom", []),
166+
classes=["sd-card-img-bottom", *options.get("class-img-bottom", [])],
164167
)
165168
container.append(image_bottom)
166169

@@ -225,7 +228,7 @@ def split_content(content: StringList, offset: int) -> CardContent:
225228
return CardContent(body, header, footer)
226229

227230
@classmethod
228-
def _create_component(
231+
def _create_component( # noqa: PLR0913
229232
cls,
230233
inst: SphinxDirective,
231234
name: str,
@@ -235,7 +238,7 @@ def _create_component(
235238
) -> nodes.container:
236239
"""Create the header, body, or footer."""
237240
component = create_component(
238-
f"card-{name}", [f"sd-card-{name}"] + options.get(f"class-{name}", [])
241+
f"card-{name}", [f"sd-card-{name}", *options.get(f"class-{name}", [])]
239242
)
240243
inst.set_source_info(component) # TODO set proper lines
241244
inst.state.nested_parse(content, offset, component)
@@ -246,9 +249,7 @@ def _create_component(
246249
def add_card_child_classes(node):
247250
"""Add classes to specific child nodes."""
248251
for para in findall(node)(nodes.paragraph):
249-
para["classes"] = ([] if "classes" not in para else para["classes"]) + [
250-
"sd-card-text"
251-
]
252+
para["classes"] = [*para.get("classes", []), "sd-card-text"]
252253
# for title in findall(node)(nodes.title):
253254
# title["classes"] = ([] if "classes" not in title else title["classes"]) + [
254255
# "sd-card-title"
@@ -273,11 +274,15 @@ def run(self) -> List[nodes.Node]:
273274
self.arguments[0].strip()
274275
)
275276
except ValueError as exc:
276-
raise self.error(f"Invalid directive argument: {exc}")
277+
raise self.error(f"Invalid directive argument: {exc}") from exc
277278
container = create_component(
278279
"card-carousel",
279-
["sd-sphinx-override", "sd-cards-carousel", f"sd-card-cols-{cols}"]
280-
+ self.options.get("class", []),
280+
[
281+
"sd-sphinx-override",
282+
"sd-cards-carousel",
283+
f"sd-card-cols-{cols}",
284+
*self.options.get("class", []),
285+
],
281286
)
282287
self.set_source_info(container)
283288
self.state.nested_parse(self.content, self.content_offset, container)

sphinx_design/dropdown.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
"""Originally Adapted from sphinxcontrib.details.directive
2-
"""
1+
"""Originally Adapted from sphinxcontrib.details.directive"""
2+
33
from docutils import nodes
44
from docutils.parsers.rst import directives
55
from sphinx.application import Sphinx
@@ -25,11 +25,11 @@ def setup_dropdown(app: Sphinx) -> None:
2525
app.add_post_transform(DropdownHtmlTransform)
2626

2727

28-
class dropdown_main(nodes.Element, nodes.General):
28+
class dropdown_main(nodes.Element, nodes.General): # noqa: N801
2929
pass
3030

3131

32-
class dropdown_title(nodes.TextElement, nodes.General):
32+
class dropdown_title(nodes.TextElement, nodes.General): # noqa: N801
3333
pass
3434

3535

sphinx_design/extension.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,10 @@ def run(self):
122122
classes = directives.class_option(self.arguments[0])
123123
else:
124124
classes = []
125-
except ValueError:
125+
except ValueError as exc:
126126
raise self.error(
127-
'Invalid class attribute value for "%s" directive: "%s".'
128-
% (self.name, self.arguments[0])
129-
)
127+
f'Invalid class attribute value for "{self.name}" directive: "{self.arguments[0]}".'
128+
) from exc
130129
node = create_component("div", rawtext="\n".join(self.content), classes=classes)
131130
if "style" in self.options:
132131
node["style"] = self.options["style"]

sphinx_design/grids.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def _media_option(
6060
continue
6161
try:
6262
int_value = int(value)
63-
except Exception:
64-
raise ValueError(validate_error_msg)
63+
except Exception as exc:
64+
raise ValueError(validate_error_msg) from exc
6565
if not (min_num <= int_value <= max_num):
6666
raise ValueError(validate_error_msg)
6767
return [f"{prefix}{values[0]}"] + [
@@ -118,7 +118,7 @@ def run(self) -> List[nodes.Node]:
118118
row_columns_option(self.arguments[0]) if self.arguments else []
119119
)
120120
except ValueError as exc:
121-
raise self.error(f"Invalid directive argument: {exc}")
121+
raise self.error(f"Invalid directive argument: {exc}") from exc
122122
self.assert_has_content()
123123
# container-fluid is 100% width for all breakpoints,
124124
# rather than the fixed width of the breakpoint (like container)
@@ -251,11 +251,11 @@ def run(self) -> List[nodes.Node]:
251251
[
252252
"sd-col",
253253
"sd-d-flex-row",
254-
]
255-
+ self.options.get("columns", [])
256-
+ self.options.get("margin", [])
257-
+ self.options.get("padding", [])
258-
+ self.options.get("class-item", []),
254+
*self.options.get("columns", []),
255+
*self.options.get("margin", []),
256+
*self.options.get("padding", []),
257+
*self.options.get("class-item", []),
258+
],
259259
)
260260
card_options = {
261261
key: value

sphinx_design/icons.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ def get_octicon(
7272
"""
7373
try:
7474
data = get_octicon_data()[name]
75-
except KeyError:
76-
raise KeyError(f"Unrecognised octicon: {name}")
75+
except KeyError as exc:
76+
raise KeyError(f"Unrecognised octicon: {name}") from exc
7777

7878
match = HEIGHT_REGEX.match(height)
7979
if not match:
@@ -85,7 +85,7 @@ def get_octicon(
8585

8686
original_height = 16
8787
if "16" not in data["heights"]:
88-
original_height = int(list(data["heights"].keys())[0])
88+
original_height = int(next(iter(data["heights"].keys())))
8989
elif "24" in data["heights"]:
9090
if height_unit == "px":
9191
if height_value >= 24:
@@ -172,7 +172,7 @@ def run(self) -> List[nodes.Node]:
172172
return [list_node]
173173

174174

175-
class fontawesome(nodes.Element, nodes.General):
175+
class fontawesome(nodes.Element, nodes.General): # noqa: N801
176176
"""Node for rendering fontawesome icon."""
177177

178178

@@ -191,7 +191,7 @@ def run(self) -> Tuple[List[nodes.Node], List[nodes.system_message]]:
191191
icon, classes = self.text.split(";", 1) if ";" in self.text else [self.text, ""]
192192
icon = icon.strip()
193193
node = fontawesome(
194-
icon=icon, classes=[self.style, f"fa-{icon}"] + classes.split()
194+
icon=icon, classes=[self.style, f"fa-{icon}", *classes.split()]
195195
)
196196
self.set_source_info(node)
197197
return [node], []
@@ -257,8 +257,8 @@ def get_material_icon(
257257
"""
258258
try:
259259
data = get_material_icon_data(style)[name]
260-
except KeyError:
261-
raise KeyError(f"Unrecognised material-{style} icon: {name}")
260+
except KeyError as exc:
261+
raise KeyError(f"Unrecognised material-{style} icon: {name}") from exc
262262

263263
match = HEIGHT_REGEX.match(height)
264264
if not match:
@@ -270,7 +270,7 @@ def get_material_icon(
270270

271271
original_height = 20
272272
if "20" not in data["heights"]:
273-
original_height = int(list(data["heights"].keys())[0])
273+
original_height = int(next(iter(data["heights"].keys())))
274274
elif "24" in data["heights"]:
275275
if height_unit == "px":
276276
if height_value >= 24:

0 commit comments

Comments
 (0)