From 42008984632607cb815c8b493eba9f3fd895b8f2 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 28 Feb 2023 11:07:31 +0100 Subject: [PATCH 1/3] pre-commit: Replace flake8, isort, and pyupgrade with ruff --- .pre-commit-config.yaml | 16 ++++------------ .ruff.toml | 26 ++++++++++++++++++++++++++ MANIFEST.in | 8 ++++---- 3 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 .ruff.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b105884..b1506c68 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,16 +10,8 @@ repos: - id: end-of-file-fixer exclude: '.*\.pth$' - id: debug-statements - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.253 hooks: - - id: isort - - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 - hooks: - - id: pyupgrade - args: [--py37-plus] - - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 - hooks: - - id: flake8 + - id: ruff + # args: [--fix, --exit-non-zero-on-fix] diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 00000000..f285d165 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,26 @@ +# [tool.ruff] # <- TODO Uncomment when migrating to pyproject.toml +exclude = [ + ".eggs", + ".tox", + "build", + "ci/templates", + "dist", +] +line-length = 140 +select = [ + "E", + "F", + "I", + "PLC", + "PLE", + "UP", + "W", +] +target-version = "py37" + +# [tool.ruff.isort] # <- TODO Uncomment when migrating to pyproject.toml +[isort] +# default-section = "THIRDPARTY" +force-single-line = true +forced-separate = ["test_pytest_cov"] +known-first-party = ["pytest_cov"] diff --git a/MANIFEST.in b/MANIFEST.in index cbb88f74..ebf88344 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,22 +7,22 @@ prune examples/adhoc-layout/*.egg-info prune examples/src-layout/src/*.egg-info graft .github/workflows -graft src graft ci +graft src graft tests include .bumpversion.cfg include .cookiecutterrc include .coveragerc include .editorconfig -include tox.ini -include .readthedocs.yml include .pre-commit-config.yaml +include .readthedocs.yml +include .ruff.toml include AUTHORS.rst include CHANGELOG.rst include CONTRIBUTING.rst include LICENSE include README.rst - +include tox.ini global-exclude *.py[cod] __pycache__/* *.so *.dylib From 430f0c862a55964a14e258c80411bf07b6e5e65d Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 20 Mar 2023 17:40:01 +0100 Subject: [PATCH 2/3] Make changes requested in code review --- .pre-commit-config.yaml | 2 +- .ruff.toml | 49 +++++++++++++++++---- examples/adhoc-layout/tests/test_example.py | 2 +- examples/src-layout/tests/test_example.py | 2 +- setup.cfg | 12 ----- src/pytest_cov/embed.py | 7 +-- src/pytest_cov/engine.py | 2 - src/pytest_cov/plugin.py | 9 ++-- tests/contextful.py | 8 ++-- tox.ini | 4 +- 10 files changed, 55 insertions(+), 42 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b1506c68..cb3c1e2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,4 +14,4 @@ repos: rev: v0.0.253 hooks: - id: ruff - # args: [--fix, --exit-non-zero-on-fix] + args: [--fix, --exit-non-zero-on-fix, --show-fixes] diff --git a/.ruff.toml b/.ruff.toml index f285d165..12fe797c 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -6,16 +6,33 @@ exclude = [ "ci/templates", "dist", ] -line-length = 140 -select = [ - "E", - "F", - "I", - "PLC", - "PLE", - "UP", - "W", +ignore = [ + "ANN", # flake8-annotations + "ARG", # flake8-unused-arguments + "BLE", # flake8-blind-except + "COM", # flake8-comma + "D", # pydocstyle + "EM", # flake8-errmsg + "FBT", # flake8-boolean-trap + "INP", # flake8-no-pep420 + "PLR0133", # Pylint Refactor + "PLR2004", # Pylint Refactor + "PLW", # Pylint Warning + "PTH", # flake8-use-pathlib + "Q", # flake8-quotes + "RET", # flake8-return + "RUF100", # Ruff-internal + "S101", # flake8-bandit assert + "S102", # flake8-bandit exec + "S110", # flake8-bandit try-except-pass + "SIM102", # flake8-simplify collapsible-if + "SIM105", # flake8-simplify use-contextlib-suppress + "SLF", # flake8-self + "T20", # flake8-print + "TRY", # tryceratops ] +line-length = 140 +select = ["ALL"] target-version = "py37" # [tool.ruff.isort] # <- TODO Uncomment when migrating to pyproject.toml @@ -24,3 +41,17 @@ target-version = "py37" force-single-line = true forced-separate = ["test_pytest_cov"] known-first-party = ["pytest_cov"] + +[mccabe] +max-complexity = 12 + +[per-file-ignores] +"ci/bootstrap.py" = ["S701"] +"docs/conf.py" = ["A001"] +"src/pytest_cov/plugin.py" = ["B904", "PT004"] +"setup.py" = ["SIM117"] +"tests/test_pytest_cov.py" = ["N801", "PT004", "RSE102", "SIM117"] + +[pylint] +max-args = 8 +max-branches = 13 diff --git a/examples/adhoc-layout/tests/test_example.py b/examples/adhoc-layout/tests/test_example.py index f4948e66..8cf207de 100644 --- a/examples/adhoc-layout/tests/test_example.py +++ b/examples/adhoc-layout/tests/test_example.py @@ -3,4 +3,4 @@ def test_add(): assert example.add(1, 1) == 2 - assert not example.add(0, 1) == 2 + assert example.add(0, 1) != 2 diff --git a/examples/src-layout/tests/test_example.py b/examples/src-layout/tests/test_example.py index f4948e66..8cf207de 100644 --- a/examples/src-layout/tests/test_example.py +++ b/examples/src-layout/tests/test_example.py @@ -3,4 +3,4 @@ def test_add(): assert example.add(1, 1) == 2 - assert not example.add(0, 1) == 2 + assert example.add(0, 1) != 2 diff --git a/setup.cfg b/setup.cfg index 360a416d..268333ec 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,3 @@ -[flake8] -max-line-length = 140 -exclude = .tox,.eggs,ci/templates,build,dist - [tool:pytest] testpaths = tests python_files = test_*.py @@ -9,11 +5,3 @@ addopts = -ra --strict -p pytester - -[tool:isort] -force_single_line = True -line_length = 120 -known_first_party = pytest_cov -default_section = THIRDPARTY -forced_separate = test_pytest_cov -skip = .tox,.eggs,ci/templates,build,dist diff --git a/src/pytest_cov/embed.py b/src/pytest_cov/embed.py index f8a2749f..be50a50b 100644 --- a/src/pytest_cov/embed.py +++ b/src/pytest_cov/embed.py @@ -38,10 +38,7 @@ def init(): import coverage # Determine all source roots. - if cov_source in os.pathsep: - cov_source = None - else: - cov_source = cov_source.split(os.pathsep) + cov_source = None if cov_source in os.pathsep else cov_source.split(os.pathsep) if cov_config == os.pathsep: cov_config = True @@ -108,7 +105,7 @@ def _signal_cleanup_handler(signum, frame): elif signum == signal.SIGTERM: os._exit(128 + signum) elif signum == signal.SIGINT: - raise KeyboardInterrupt() + raise KeyboardInterrupt def cleanup_on_signal(signum): diff --git a/src/pytest_cov/engine.py b/src/pytest_cov/engine.py index 27e1a090..91e32169 100644 --- a/src/pytest_cov/engine.py +++ b/src/pytest_cov/engine.py @@ -412,5 +412,3 @@ def finish(self): def summary(self, stream): """Only the master reports so do nothing.""" - - pass diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index dd7b8c4e..4dfab1a0 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -35,7 +35,7 @@ def validate_report(arg): all_choices = term_choices + file_choices values = arg.split(":", 1) report_type = values[0] - if report_type not in all_choices + ['']: + if report_type not in [*all_choices, '']: msg = f'invalid choice: "{arg}" (choose from "{all_choices}")' raise argparse.ArgumentTypeError(msg) @@ -247,7 +247,7 @@ def pytest_sessionstart(self, session): self.pid = os.getpid() if self._is_worker(session): nodeid = ( - session.config.workerinput.get('workerid', getattr(session, 'nodeid')) + session.config.workerinput.get('workerid', session.nodeid) ) self.start(engine.DistWorker, session.config, nodeid) elif not self._started: @@ -389,13 +389,12 @@ def switch_context(self, item, when): os.environ['COV_CORE_CONTEXT'] = context -@pytest.fixture +@pytest.fixture() def no_cover(): """A pytest fixture to disable coverage.""" - pass -@pytest.fixture +@pytest.fixture() def cov(request): """A pytest fixture to provide access to the underlying coverage object.""" diff --git a/tests/contextful.py b/tests/contextful.py index 3527e499..7edb87c0 100644 --- a/tests/contextful.py +++ b/tests/contextful.py @@ -39,7 +39,7 @@ def test_04(self): assert self.items[0] == "hello" # r4 -@pytest.fixture +@pytest.fixture() def some_data(): return [1, 2, 3] # s5 s6 @@ -48,7 +48,7 @@ def test_05(some_data): assert len(some_data) == 3 # r5 -@pytest.fixture +@pytest.fixture() def more_data(some_data): return [2*x for x in some_data] # s6 @@ -83,7 +83,7 @@ def test_10(): assert 1 == 1 # r10 -@pytest.mark.parametrize("x, ans", [ +@pytest.mark.parametrize(("x", "ans"), [ (1, 101), (2, 202), ]) @@ -91,7 +91,7 @@ def test_11(x, ans): assert 100 * x + x == ans # r11-1 r11-2 -@pytest.mark.parametrize("x, ans", [ +@pytest.mark.parametrize(("x", "ans"), [ (1, 101), (2, 202), ], ids=['one', 'two']) diff --git a/tox.ini b/tox.ini index aeccd9de..fe1c20cc 100644 --- a/tox.ini +++ b/tox.ini @@ -93,14 +93,14 @@ deps = check-manifest colorama # TODO Remove when isort > v6.0.0b2 is released. docutils - flake8 isort pygments readme-renderer + ruff skip_install = true usedevelop = false commands = python setup.py check --strict --metadata --restructuredtext check-manifest {toxinidir} - flake8 src tests setup.py + ruff . isort --check-only --diff src tests setup.py From 469085c29e662a7dc6746faf4bfcdd086fdfbe24 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 20 Mar 2023 18:51:07 +0100 Subject: [PATCH 3/3] Add ruff per-file-ignores --- src/pytest_cov/plugin.py | 4 ++-- tests/test_pytest_cov.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index 4dfab1a0..a406eb33 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -308,7 +308,7 @@ def pytest_runtestloop(self, session): message = 'Failed to generate report: %s\n' % exc session.config.pluginmanager.getplugin("terminalreporter").write( 'WARNING: %s\n' % message, red=True, bold=True) - warnings.warn(CovReportWarning(message)) + warnings.warn(CovReportWarning(message)) # noqa: B028 self.cov_total = 0 assert self.cov_total is not None, 'Test coverage should never be `None`' if self._failed_cov_total() and not self.options.collectonly: @@ -320,7 +320,7 @@ def pytest_terminal_summary(self, terminalreporter): if self.options.no_cov_should_warn: message = 'Coverage disabled via --no-cov switch!' terminalreporter.write('WARNING: %s\n' % message, red=True, bold=True) - warnings.warn(CovDisabledWarning(message)) + warnings.warn(CovDisabledWarning(message)) # noqa: B028 return if self.cov_controller is None: return diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 77859bf4..d1f10a20 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -1945,7 +1945,7 @@ def test_contexts(pytester, testdir, opts): line_data = find_labels(contextful_tests, r"[crst]\d+(?:-\d+)?") for context, label in EXPECTED_CONTEXTS.items(): - if context == '': + if context == '': # noqa: PLC1901 continue data.set_query_context(context) actual = set(data.lines(test_context_path))