Skip to content

Commit c11cdfa

Browse files
Migrate from autoflake, black, isort, pyupgrade, flake8 and pydocstyle, to ruff (#11911)
ruff is faster and handle everything we had prior. isort configuration done based on the indication from astral-sh/ruff#4670, previousely based on reorder-python-import (#11896) flake8-docstrings was a wrapper around pydocstyle (now archived) that explicitly asks to use ruff in PyCQA/pydocstyle#658. flake8-typing-import is useful mainly for project that support python 3.7 and the one useful check will be implemented in astral-sh/ruff#2302 We need to keep blacken-doc because ruff does not handle detection of python code inside .md and .rst. The direct link to the repo is now used to avoid a redirection. Manual fixes: - Lines that became too long - % formatting that was not done automatically - type: ignore that were moved around - noqa of hard to fix issues (UP031 generally) - fmt: off and fmt: on that is not really identical between black and ruff - autofix re-order in pre-commit from faster to slower Co-authored-by: Ran Benita <[email protected]>
1 parent 368cc62 commit c11cdfa

File tree

151 files changed

+789
-955
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+789
-955
lines changed

.pre-commit-config.yaml

+10-36
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
repos:
2-
- repo: https://github.com/psf/black
3-
rev: 24.1.1
4-
hooks:
5-
- id: black
6-
args: [--safe, --quiet]
7-
- repo: https://github.com/asottile/blacken-docs
8-
rev: 1.16.0
9-
hooks:
10-
- id: blacken-docs
11-
additional_dependencies: [black==24.1.1]
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: "v0.1.15"
4+
hooks:
5+
- id: ruff
6+
args: ["--fix"]
7+
- id: ruff-format
128
- repo: https://github.com/pre-commit/pre-commit-hooks
139
rev: v4.5.0
1410
hooks:
@@ -20,33 +16,11 @@ repos:
2016
- id: debug-statements
2117
exclude: _pytest/(debugging|hookspec).py
2218
language_version: python3
23-
- repo: https://github.com/PyCQA/autoflake
24-
rev: v2.2.1
25-
hooks:
26-
- id: autoflake
27-
name: autoflake
28-
args: ["--in-place", "--remove-unused-variables", "--remove-all-unused-imports"]
29-
language: python
30-
files: \.py$
31-
- repo: https://github.com/PyCQA/flake8
32-
rev: 6.1.0
33-
hooks:
34-
- id: flake8
35-
language_version: python3
36-
additional_dependencies:
37-
- flake8-typing-imports==1.12.0
38-
- flake8-docstrings==1.5.0
39-
- repo: https://github.com/pycqa/isort
40-
rev: 5.13.2
41-
hooks:
42-
- id: isort
43-
name: isort
44-
args: [--force-single-line, --profile=black]
45-
- repo: https://github.com/asottile/pyupgrade
46-
rev: v3.15.0
19+
- repo: https://github.com/adamchainz/blacken-docs
20+
rev: 1.16.0
4721
hooks:
48-
- id: pyupgrade
49-
args: [--py38-plus]
22+
- id: blacken-docs
23+
additional_dependencies: [black==24.1.1]
5024
- repo: https://github.com/asottile/setup-cfg-fmt
5125
rev: v2.5.0
5226
hooks:

README.rst

-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
:target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main
2828
:alt: pre-commit.ci status
2929

30-
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
31-
:target: https://github.com/psf/black
32-
3330
.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
3431
:target: https://www.codetriage.com/pytest-dev/pytest
3532

bench/bench.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22

3+
34
if __name__ == "__main__":
45
import cProfile
56
import pstats

bench/bench_argcomplete.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# FastFilesCompleter 0.7383 1.0760
55
import timeit
66

7+
78
imports = [
89
"from argcomplete.completers import FilesCompleter as completer",
910
"from _pytest._argcomplete import FastFilesCompleter as completer",

bench/skip.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22

3+
34
SKIP = True
45

56

bench/unit_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from unittest import TestCase # noqa: F401
22

3+
34
for i in range(15000):
45
exec(
56
f"""

doc/en/conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from _pytest import __version__ as version
2525

26+
2627
if TYPE_CHECKING:
2728
import sphinx.application
2829

doc/en/example/assertion/global_testmodule_config/conftest.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
56
mydir = os.path.dirname(__file__)
67

78

doc/en/example/assertion/test_failures.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os.path
22
import shutil
33

4+
45
failure_demo = os.path.join(os.path.dirname(__file__), "failure_demo.py")
56
pytest_plugins = ("pytester",)
67

doc/en/example/multipython.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import pytest
99

10+
1011
pythonlist = ["python3.9", "python3.10", "python3.11"]
1112

1213

@@ -32,14 +33,12 @@ def dumps(self, obj):
3233
dumpfile = self.picklefile.with_name("dump.py")
3334
dumpfile.write_text(
3435
textwrap.dedent(
35-
r"""
36+
rf"""
3637
import pickle
37-
f = open({!r}, 'wb')
38-
s = pickle.dump({!r}, f, protocol=2)
38+
f = open({str(self.picklefile)!r}, 'wb')
39+
s = pickle.dump({obj!r}, f, protocol=2)
3940
f.close()
40-
""".format(
41-
str(self.picklefile), obj
42-
)
41+
"""
4342
)
4443
)
4544
subprocess.run((self.pythonpath, str(dumpfile)), check=True)
@@ -48,17 +47,15 @@ def load_and_is_true(self, expression):
4847
loadfile = self.picklefile.with_name("load.py")
4948
loadfile.write_text(
5049
textwrap.dedent(
51-
r"""
50+
rf"""
5251
import pickle
53-
f = open({!r}, 'rb')
52+
f = open({str(self.picklefile)!r}, 'rb')
5453
obj = pickle.load(f)
5554
f.close()
56-
res = eval({!r})
55+
res = eval({expression!r})
5756
if not res:
5857
raise SystemExit(1)
59-
""".format(
60-
str(self.picklefile), expression
61-
)
58+
"""
6259
)
6360
)
6461
print(loadfile)

doc/en/example/xfail_demo.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22

3+
34
xfail = pytest.mark.xfail
45

56

extra/get_issues.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import requests
55

6+
67
issues_url = "https://api.github.com/repos/pytest-dev/pytest/issues"
78

89

pyproject.toml

+55
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,58 @@ target-version = ['py38']
123123
[tool.check-wheel-contents]
124124
# W009: Wheel contains multiple toplevel library entries
125125
ignore = "W009"
126+
127+
[tool.ruff]
128+
src = ["src"]
129+
line-length = 88
130+
select = [
131+
"D", # pydocstyle
132+
"E", # pycodestyle
133+
"F", # pyflakes
134+
"I", # isort
135+
"UP", # pyupgrade
136+
"W", # pycodestyle
137+
]
138+
ignore = [
139+
# pycodestyle ignore
140+
# pytest can do weird low-level things, and we usually know
141+
# what we're doing when we use type(..) is ...
142+
"E721", # Do not compare types, use `isinstance()`
143+
# pydocstyle ignore
144+
"D100", # Missing docstring in public module
145+
"D101", # Missing docstring in public class
146+
"D102", # Missing docstring in public method
147+
"D103", # Missing docstring in public function
148+
"D104", # Missing docstring in public package
149+
"D105", # Missing docstring in magic method
150+
"D106", # Missing docstring in public nested class
151+
"D107", # Missing docstring in `__init__`
152+
"D209", # [*] Multi-line docstring closing quotes should be on a separate line
153+
"D205", # 1 blank line required between summary line and description
154+
"D400", # First line should end with a period
155+
"D401", # First line of docstring should be in imperative mood
156+
"D402", # First line should not be the function's signature
157+
"D404", # First word of the docstring should not be "This"
158+
"D415", # First line should end with a period, question mark, or exclamation point
159+
# Temp for backport 8.0.x
160+
"E501",
161+
"UP031",
162+
]
163+
164+
[tool.ruff.format]
165+
docstring-code-format = true
166+
167+
[tool.ruff.lint.pycodestyle]
168+
# In order to be able to format for 88 char in ruff format
169+
max-line-length = 120
170+
171+
[tool.ruff.lint.pydocstyle]
172+
convention = "pep257"
173+
174+
[tool.ruff.lint.isort]
175+
force-single-line = true
176+
combine-as-imports = true
177+
force-sort-within-sections = true
178+
order-by-type = false
179+
known-local-folder = ["pytest", "_pytest"]
180+
lines-after-imports = 2

scripts/generate-gh-release-notes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
99
Requires Python3.6+.
1010
"""
11+
from pathlib import Path
1112
import re
1213
import sys
13-
from pathlib import Path
1414
from typing import Sequence
1515

1616
import pypandoc

scripts/prepare-release-pr.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
`pytest bot <[email protected]>` commit author.
1515
"""
1616
import argparse
17-
import re
1817
from pathlib import Path
18+
import re
1919
from subprocess import check_call
2020
from subprocess import check_output
2121
from subprocess import run

scripts/towncrier-draft-to-file.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# mypy: disallow-untyped-defs
2-
import sys
32
from subprocess import call
3+
import sys
44

55

66
def main() -> int:

scripts/update-plugin-list.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111

1212
import packaging.version
1313
import platformdirs
14-
import tabulate
15-
import wcwidth
1614
from requests_cache import CachedResponse
1715
from requests_cache import CachedSession
1816
from requests_cache import OriginalResponse
1917
from requests_cache import SQLiteCache
18+
import tabulate
2019
from tqdm import tqdm
20+
import wcwidth
21+
2122

2223
FILE_HEAD = r"""
2324
.. Note this file is autogenerated by scripts/update-plugin-list.py - usually weekly via github action
@@ -85,7 +86,6 @@ def project_response_with_refresh(
8586
8687
force refresh in case of last serial mismatch
8788
"""
88-
8989
response = session.get(f"https://pypi.org/pypi/{name}/json")
9090
if int(response.headers.get("X-PyPI-Last-Serial", -1)) != last_serial:
9191
response = session.get(f"https://pypi.org/pypi/{name}/json", refresh=True)
@@ -184,7 +184,6 @@ def version_sort_key(version_string: str) -> Any:
184184

185185
def plugin_definitions(plugins: Iterable[PluginInfo]) -> Iterator[str]:
186186
"""Return RST for the plugin list that fits better on a vertical page."""
187-
188187
for plugin in plugins:
189188
yield dedent(
190189
f"""

src/_pytest/_argcomplete.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@
6363
"""
6464

6565
import argparse
66+
from glob import glob
6667
import os
6768
import sys
68-
from glob import glob
6969
from typing import Any
7070
from typing import List
7171
from typing import Optional

src/_pytest/_code/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .source import getrawcode
1111
from .source import Source
1212

13+
1314
__all__ = [
1415
"Code",
1516
"ExceptionInfo",

0 commit comments

Comments
 (0)