Skip to content

Commit

Permalink
Support old pytests (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
iurisilvio committed Mar 3, 2024
1 parent 463bb48 commit 37b8e73
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 21 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
build-backend = "poetry_dynamic_versioning.backend"

[tool.poetry.dependencies]
pytest = ">=5"
python = "^3.8"
ruff = ">=0.0.242"

[tool.poetry.group.dev.dependencies]
pytest = "^7.2.0"
pytest-mock = "^3.10.0"
pytest-cov = "^4.1.0"

Expand Down
28 changes: 14 additions & 14 deletions pytest_ruff.py → pytest_ruff/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from subprocess import Popen, PIPE

# Python<=3.8 don't support typing with builtin dict.
from typing import Dict

import pytest

from ruff.__main__ import find_ruff_bin

from pytest_ruff._pytest_compat import get_stash, make_path_kwargs, set_stash

HISTKEY = "ruff/mtimes"
_MTIMES_STASH_KEY = pytest.StashKey[Dict[str, float]]()


def pytest_addoption(parser):
Expand All @@ -24,18 +23,18 @@ def pytest_configure(config):
if not config.option.ruff or not hasattr(config, "cache"):
return

config.stash[_MTIMES_STASH_KEY] = config.cache.get(HISTKEY, {})
set_stash(config, config.cache.get(HISTKEY, {}))


def pytest_collect_file(file_path, path, parent):
def pytest_collect_file(path, parent, fspath=None):
config = parent.config
if not config.option.ruff:
return

if file_path.suffix != ".py":
if path.ext != ".py":
return

return RuffFile.from_parent(parent, path=file_path)
return RuffFile.from_parent(parent, **make_path_kwargs(path))


def pytest_sessionfinish(session, exitstatus):
Expand All @@ -48,7 +47,7 @@ def pytest_sessionfinish(session, exitstatus):
# It works fine if pytest-xdist is not being used.
if not hasattr(config, "workerinput"):
cache = config.cache.get(HISTKEY, {})
cache.update(config.stash[_MTIMES_STASH_KEY])
cache.update(get_stash(config))
config.cache.set(HISTKEY, cache)


Expand Down Expand Up @@ -93,16 +92,17 @@ def __init__(self, *k, **kwargs):
self.add_marker("ruff")

def setup(self):
ruffmtimes = self.config.stash.get(_MTIMES_STASH_KEY, {})
ruffmtimes = get_stash(self.config)
self._ruffmtime = self.fspath.mtime()
old = ruffmtimes.get(str(self.fspath))
if old == self._ruffmtime:
pytest.skip("file previously passed ruff checks")
if ruffmtimes:
old = ruffmtimes.get(str(self.fspath))
if old == self._ruffmtime:
pytest.skip("file previously passed ruff checks")

def runtest(self):
self.handler(path=self.fspath)

ruffmtimes = self.config.stash.get(_MTIMES_STASH_KEY, None)
ruffmtimes = get_stash(self.config)
if ruffmtimes:
ruffmtimes[str(self.fspath)] = self._ruffmtime

Expand Down
46 changes: 46 additions & 0 deletions pytest_ruff/_pytest_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from pathlib import Path

# Python<=3.8 don't support typing with builtin dict.
from typing import Dict

import pytest

try:
from pytest import Stash, StashKey
except ImportError:
import _pytest.store

Stash = _pytest.store.Store
StashKey = _pytest.store.StoreKey

PYTEST_VER = tuple(int(x) for x in pytest.__version__.split(".")[:2])
_MTIMES_STASH_KEY = StashKey[Dict[str, float]]()


def make_path_kwargs(p):
"""
Make keyword arguments passing either path or fspath, depending on pytest version.
In pytest 7.0, the `fspath` argument to Nodes has been deprecated, so we pass `path`
instead.
"""
return dict(path=Path(p)) if PYTEST_VER >= (7, 0) else dict(fspath=p)


def get_stash_object(config):
try:
stash = config.stash
except AttributeError:
stash = config._store
return stash


def get_stash(config):
missing = object()
stash = get_stash_object(config).get(_MTIMES_STASH_KEY, default=missing)
assert stash is not missing
return stash


def set_stash(config, value):
get_stash_object(config)[_MTIMES_STASH_KEY] = value
12 changes: 7 additions & 5 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@
import pytest

import pytest_ruff
from pytest_ruff._pytest_compat import Stash, get_stash


def test_configure(mocker):
config = mocker.Mock(
cache={pytest_ruff.HISTKEY: mocker.sentinel.cache},
option=mocker.Mock(ruff=True),
stash=pytest.Stash(),
stash=Stash(),
)
pytest_ruff.pytest_configure(config)
assert config.stash[pytest_ruff._MTIMES_STASH_KEY] == mocker.sentinel.cache
assert get_stash(config) == mocker.sentinel.cache


def test_configure_without_ruff(mocker):
config = mocker.Mock(
option=mocker.Mock(ruff=False),
stash=pytest.Stash(),
# Mocking to `not hasattr(config, "cache")`.
spec=["addinivalue_line", "option", "stash"],
)
set_stash_mock = mocker.patch("pytest_ruff.set_stash", spec=True)
pytest_ruff.pytest_configure(config)
with pytest.raises(KeyError):
config.stash[pytest_ruff._MTIMES_STASH_KEY]
set_stash_mock.assert_not_called()


def test_check_file():
Expand Down Expand Up @@ -61,6 +61,7 @@ def test_pytest_ruff_format():
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
).communicate()
assert err.decode() == ""
assert "File would be reformatted" in out.decode("utf-8")


Expand All @@ -76,4 +77,5 @@ def test_pytest_ruff_noformat():
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
).communicate()
assert err.decode() == ""
assert "File would be reformatted" not in out.decode("utf-8")
10 changes: 9 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
[tox]
isolated_build = true
envlist = py{38,39,310,311,312},lint
envlist = py{38,39,310,311,312}-pytest{5,6,7,8},lint

[testenv]
allowlist_externals = poetry
commands =
poetry install --no-root --with dev
pytest5: pip install "pytest<6"
pytest6: pip install "pytest>=6,<7"
pytest7: pip install "pytest>=7,<8"
pytest8: pip install "pytest>=8,<9"
# Disable ruff plugin to generate better coverage results
poetry run pytest -p no:ruff -vvv --cov --cov-append --cov-report term --cov-report xml {posargs}

# pytest 5 does not work on python>=3.10
[testenv:py{310,311,312}-pytest{5}]
ignore_outcome = true

[testenv:lint]
description = lint source code
deps =
Expand Down

0 comments on commit 37b8e73

Please sign in to comment.