Skip to content

Commit 4588653

Browse files
Migrate from autoflake, black, isort, pyupgrade, flake8 and pydocstyle, to ruff
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 046f647 commit 4588653

File tree

149 files changed

+799
-971
lines changed

Some content is hidden

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

149 files changed

+799
-971
lines changed

Diff for: .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: 7.0.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:

Diff for: 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

Diff for: 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

Diff for: 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",

Diff for: 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

Diff for: 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"""

Diff for: 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

Diff for: 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

Diff for: 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

Diff for: 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)

Diff for: 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

Diff for: 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

Diff for: pyproject.toml

+52
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,55 @@ 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+
]
160+
161+
[tool.ruff.format]
162+
docstring-code-format = true
163+
164+
[tool.ruff.lint.pycodestyle]
165+
# In order to be able to format for 88 char in ruff format
166+
max-line-length = 120
167+
168+
[tool.ruff.lint.pydocstyle]
169+
convention = "pep257"
170+
171+
[tool.ruff.lint.isort]
172+
force-single-line = true
173+
combine-as-imports = true
174+
force-sort-within-sections = true
175+
order-by-type = false
176+
known-local-folder = ["pytest", "_pytest"]
177+
lines-after-imports = 2

Diff for: 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

Diff for: 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

Diff for: 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:

Diff for: 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"""

Diff for: 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

Diff for: 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)