Skip to content

Commit 9633775

Browse files
committed
Migrate to ruff.
1 parent f2556ea commit 9633775

38 files changed

+445
-409
lines changed

.flake8

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

.pre-commit-config.yaml

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
11
repos:
2-
- hooks:
3-
- id: black
4-
language_version: python3
5-
repo: https://github.com/ambv/black
6-
rev: 24.10.0
7-
- hooks:
8-
- id: isort
9-
language_version: python3
10-
repo: https://github.com/PyCQA/isort
11-
rev: 5.13.2
12-
- hooks:
13-
- id: flake8
14-
language_version: python3
15-
additional_dependencies:
16-
- flake8-bugbear
17-
- flake8-comprehensions
18-
- flake8-debugger
19-
- flake8-docstrings
20-
- flake8-string-format
21-
repo: https://github.com/pycqa/flake8
22-
rev: 7.1.1
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.13.1
4+
hooks:
5+
- id: ruff-check
6+
args: [ --fix ]
7+
- id: ruff-format

docs/conf.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010
# add these directories to sys.path here. If the directory is relative to the
1111
# documentation root, use os.path.abspath to make it absolute, like shown here.
1212
#
13-
import os
1413
import pkgutil
1514
import sys
1615
from datetime import datetime
1716
from pathlib import Path
1817

19-
sys.path.insert(0, os.path.abspath("../"))
18+
sys.path.insert(0, str(Path(__file__).parent.parent))
2019

2120

2221
def get_copyright(attribution, *, first_year):
@@ -29,7 +28,7 @@ def get_copyright(attribution, *, first_year):
2928

3029
def get_version_and_release():
3130
try:
32-
import scrapy_poet # noqa: F401
31+
import scrapy_poet # noqa: F401,PLC0415
3332
except ImportError:
3433
return "", ""
3534
version_bytes = pkgutil.get_data("scrapy_poet", "VERSION") or b""
@@ -42,7 +41,7 @@ def get_version_and_release():
4241
# -- Project information -----------------------------------------------------
4342

4443
project = "scrapy-poet"
45-
copyright = get_copyright("Zyte Group Ltd", first_year=2019)
44+
project_copyright = get_copyright("Zyte Group Ltd", first_year=2019)
4645
author = "Zyte"
4746

4847
version, release = get_version_and_release()

example/example/autoextract.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
which even requires an API request.
44
"""
55

6-
from typing import Any, Dict
6+
from typing import Any
77

88
import attr
99
from scrapy import Request
@@ -18,7 +18,7 @@
1818
class AutoextractProductResponse:
1919
"""Input data"""
2020

21-
data: Dict[str, Any]
21+
data: dict[str, Any]
2222

2323

2424
class AutoextractProductProvider(PageObjectInputProvider):
@@ -51,5 +51,4 @@ def url(self):
5151
return self.autoextract_resp.data["product"]["url"]
5252

5353
def to_item(self):
54-
product = self.autoextract_resp.data["product"]
55-
return product
54+
return self.autoextract_resp.data["product"]

example/example/spiders/books_03.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"""
44

55
import scrapy
6-
from example.autoextract import ProductPage
76

7+
from example.autoextract import ProductPage
88
from scrapy_poet import callback_for
99

1010

example/example/spiders/books_05.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"""
55

66
import scrapy
7-
from example.autoextract import ProductPage
87
from web_poet import WebPage
98

9+
from example.autoextract import ProductPage
10+
1011

1112
class BookListPage(WebPage):
1213
def product_urls(self):

example/example/spiders/books_05_1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
"""
1313

1414
import scrapy
15-
from example.autoextract import ProductPage
1615
from web_poet import WebPage
1716

17+
from example.autoextract import ProductPage
1818
from scrapy_poet import DummyResponse
1919

2020

pyproject.toml

Lines changed: 154 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[tool.black]
2-
line-length = 88
3-
41
[tool.bumpversion]
52
current_version = "0.26.0"
63
commit = true
@@ -18,6 +15,9 @@ filename = "scrapy_poet/VERSION"
1815

1916
[tool.coverage.run]
2017
branch = true
18+
patch = [
19+
"subprocess",
20+
]
2121

2222
[tool.coverage.paths]
2323
source = [
@@ -27,16 +27,9 @@ source = [
2727

2828
[tool.coverage.report]
2929
exclude_also = [
30-
"if TYPE_CHECKING:",
3130
"@(abc\\.)?abstractmethod",
3231
]
3332

34-
[tool.isort]
35-
profile = "black"
36-
multi_line_output = 3
37-
# scrapy_poet/__init__.py: Automatic sorting causes circular dependencies.
38-
skip = ["scrapy_poet/__init__.py"]
39-
4033
[[tool.mypy.overrides]]
4134
module = [
4235
"tests.test_cache.*",
@@ -48,3 +41,154 @@ module = [
4841
# when test cases are decorated with @inlineCallbacks. However, the
4942
# tests doesn't return anything at all.
5043
disable_error_code = "misc"
44+
45+
[tool.ruff.lint]
46+
extend-select = [
47+
# flake8-builtins
48+
"A",
49+
# flake8-async
50+
"ASYNC",
51+
# flake8-bugbear
52+
"B",
53+
# flake8-comprehensions
54+
"C4",
55+
# flake8-commas
56+
"COM",
57+
# pydocstyle
58+
"D",
59+
# flake8-future-annotations
60+
"FA",
61+
# flynt
62+
"FLY",
63+
# refurb
64+
"FURB",
65+
# isort
66+
"I",
67+
# flake8-implicit-str-concat
68+
"ISC",
69+
# flake8-logging
70+
"LOG",
71+
# Perflint
72+
"PERF",
73+
# pygrep-hooks
74+
"PGH",
75+
# flake8-pie
76+
"PIE",
77+
# pylint
78+
"PL",
79+
# flake8-pytest-style
80+
"PT",
81+
# flake8-use-pathlib
82+
"PTH",
83+
# flake8-pyi
84+
"PYI",
85+
# flake8-quotes
86+
"Q",
87+
# flake8-return
88+
"RET",
89+
# flake8-raise
90+
"RSE",
91+
# Ruff-specific rules
92+
"RUF",
93+
# flake8-bandit
94+
"S",
95+
# flake8-simplify
96+
"SIM",
97+
# flake8-slots
98+
"SLOT",
99+
# flake8-debugger
100+
"T10",
101+
# flake8-type-checking
102+
"TC",
103+
# flake8-tidy-imports
104+
"TID",
105+
# pyupgrade
106+
"UP",
107+
# pycodestyle warnings
108+
"W",
109+
# flake8-2020
110+
"YTT",
111+
]
112+
ignore = [
113+
# Trailing comma missing
114+
"COM812",
115+
# Missing docstring in public module
116+
"D100",
117+
# Missing docstring in public class
118+
"D101",
119+
# Missing docstring in public method
120+
"D102",
121+
# Missing docstring in public function
122+
"D103",
123+
# Missing docstring in public package
124+
"D104",
125+
# Missing docstring in magic method
126+
"D105",
127+
# Missing docstring in __init__
128+
"D107",
129+
# One-line docstring should fit on one line with quotes
130+
"D200",
131+
# No blank lines allowed after function docstring
132+
"D202",
133+
# 1 blank line required between summary line and description
134+
"D205",
135+
# Multi-line docstring closing quotes should be on a separate line
136+
"D209",
137+
# First line should end with a period
138+
"D400",
139+
# First line should be in imperative mood; try rephrasing
140+
"D401",
141+
# First line should not be the function's "signature"
142+
"D402",
143+
# Too many return statements
144+
"PLR0911",
145+
# Too many branches
146+
"PLR0912",
147+
# Too many arguments in function definition
148+
"PLR0913",
149+
# Too many statements
150+
"PLR0915",
151+
# Magic value used in comparison
152+
"PLR2004",
153+
# String contains ambiguous {}.
154+
"RUF001",
155+
# Docstring contains ambiguous {}.
156+
"RUF002",
157+
# Comment contains ambiguous {}.
158+
"RUF003",
159+
# Mutable class attributes should be annotated with `typing.ClassVar`
160+
"RUF012",
161+
# Use of `assert` detected
162+
"S101",
163+
# Yoda condition detected
164+
"SIM300",
165+
# Add `from __future__ import annotations` to simplify
166+
# (It's harder to keep annotations resolvable at the runtime with it.)
167+
"FA100",
168+
]
169+
170+
[tool.ruff.lint.flake8-tidy-imports]
171+
banned-module-level-imports = [
172+
"twisted.internet.reactor",
173+
]
174+
175+
[tool.ruff.lint.isort]
176+
split-on-trailing-comma = false
177+
178+
[tool.ruff.lint.per-file-ignores]
179+
"example/*" = ["PLC0415"]
180+
# scrapy_poet/__init__.py: Automatic import sorting causes circular dependencies.
181+
"scrapy_poet/__init__.py" = ["F401", "I"]
182+
"scrapy_poet/page_inputs/__init__.py" = ["F401"]
183+
"tests/*" = ["SLOT000", "S"]
184+
185+
# we need to use typing.Set[] over modern alternatives with web-poet<0.19.0 && Python<3.11
186+
# see https://github.com/scrapinghub/web-poet/pull/219
187+
"scrapy_poet/page_input_providers.py" = ["UP006", "UP035"]
188+
"tests/test_downloader.py" =["UP006", "UP035"]
189+
"tests/test_providers.py" =["UP006", "UP035"]
190+
"tests/test_request_fingerprinter.py" =["UP006", "UP035"]
191+
"tests/test_web_poet_rules.py" =["UP006", "UP035"]
192+
193+
[tool.ruff.lint.pydocstyle]
194+
convention = "pep257"

scrapy_poet/_addon.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ def _replace_builtin(
2222
f"{builtin_cls} entry with {new_cls}. Add {new_cls} manually to "
2323
f"silence this warning."
2424
)
25-
return None
25+
return
2626

2727
if new_cls in setting_value:
28-
return None
28+
return
2929
for cls_or_path in setting_value:
3030
if isinstance(cls_or_path, str):
3131
_cls = load_object(cls_or_path)
3232
if _cls == new_cls:
33-
return None
33+
return
3434

3535
builtin_entry: object = None
3636
for _setting_value in (setting_value, settings[f"{setting}_BASE"]):
@@ -54,7 +54,7 @@ def _replace_builtin(
5454
f"missing built-in entry {builtin_cls}. Cannot replace it with {new_cls}. "
5555
f"Add {new_cls} manually to silence this warning."
5656
)
57-
return None
57+
return
5858

5959
if pos is None:
6060
logger.warning(

0 commit comments

Comments
 (0)