Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ jobs:
- version: "3.15t"
pytest-version:
- ">=8.1.1"
# Older pytest versions only on the latest Python
include:
# Before pytest.register_fixture (private _arg2fixturedefs override)
- config: headless
python: { version: "3.15" }
pytest-version: "~=9.0.0"
- config: pytest-benchmark-5
python: { version: "3.15" }
pytest-version: "~=9.0.0"
# Before 8.1.1 (getfixturedefs takes a nodeid)
- config: headless
python: { version: "3.15" }
pytest-version: "~=8.0.0"
- config: pytest-benchmark-4
python: { version: "3.15" }
pytest-version: "~=8.0.0"

steps:
- uses: actions/checkout@v5
Expand All @@ -57,7 +73,7 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "${{ matrix.python.version }}"
- if: matrix.config == 'valgrind' || matrix.config == 'pytest-benchmark'
- if: matrix.config == 'valgrind' || startsWith(matrix.config, 'pytest-benchmark')
name: Install valgrind
run: |
sudo apt-get update
Expand Down
23 changes: 23 additions & 0 deletions src/pytest_codspeed/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from pytest_codspeed.instruments import MeasurementMode, get_instrument_from_mode
from pytest_codspeed.utils import (
BEFORE_PYTEST_8_1_1,
HAS_PYTEST_REGISTER_FIXTURE,
IS_PYTEST_BENCHMARK_INSTALLED,
IS_PYTEST_SPEED_INSTALLED,
get_environment_metadata,
Expand Down Expand Up @@ -187,6 +188,8 @@ def pytest_plugin_registered(plugin, manager: pytest.PytestPluginManager):
Patch the benchmark fixture to use the codspeed one if codspeed is enabled and an
alternative benchmark fixture is available
"""
if HAS_PYTEST_REGISTER_FIXTURE:
return # handled in pytest_sessionstart
if (IS_PYTEST_BENCHMARK_INSTALLED or IS_PYTEST_SPEED_INSTALLED) and isinstance(
plugin, FixtureManager
):
Expand All @@ -210,6 +213,26 @@ def pytest_plugin_registered(plugin, manager: pytest.PytestPluginManager):
fixture_manager._arg2fixturedefs["benchmark"] = codspeed_benchmark_fixtures


def _benchmark_compat(codspeed_benchmark, request: pytest.FixtureRequest):
return codspeed_benchmark


@pytest.hookimpl(trylast=True)
def pytest_sessionstart(session: pytest.Session):
"""
Override the benchmark fixture of pytest-benchmark/pytest-speed with the codspeed
one, using the public API available since pytest 9.1
"""
if HAS_PYTEST_REGISTER_FIXTURE and (
IS_PYTEST_BENCHMARK_INSTALLED or IS_PYTEST_SPEED_INSTALLED
):
codspeed_plugin = session.config.pluginmanager.get_plugin(PLUGIN_NAME)
if codspeed_plugin is not None and codspeed_plugin.is_codspeed_enabled:
pytest.register_fixture(
name="benchmark", func=_benchmark_compat, node=session
)


@pytest.hookimpl(trylast=True)
def pytest_report_header(config: pytest.Config):
plugin = get_plugin(config)
Expand Down
2 changes: 2 additions & 0 deletions src/pytest_codspeed/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
IS_PYTEST_BENCHMARK_INSTALLED = importlib.util.find_spec("pytest_benchmark") is not None
IS_PYTEST_SPEED_INSTALLED = importlib.util.find_spec("pytest_speed") is not None
BEFORE_PYTEST_8_1_1 = pytest.version_tuple < (8, 1, 1)
# Public API since pytest 9.1, required since 9.2 removed `_arg2fixturedefs`
HAS_PYTEST_REGISTER_FIXTURE = hasattr(pytest, "register_fixture")
SUPPORTS_PERF_TRAMPOLINE = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") == 1


Expand Down
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
skip_with_pytest_benchmark = pytest.mark.skipif(
IS_PYTEST_BENCHMARK_INSTALLED, reason="pytest_benchmark installed"
)
xfail_pytest_benchmark_on_pytest_9_2 = pytest.mark.xfail(
IS_PYTEST_BENCHMARK_INSTALLED and pytest.version_tuple >= (9, 2),
reason="pytest-benchmark is incompatible with pytest 9.2 (Node._nodeid removal)",
strict=False,
)
if IS_PYTEST_BENCHMARK_INSTALLED:
pytest_plugins.append("pytest_benchmark")
print(
Expand Down
3 changes: 3 additions & 0 deletions tests/test_pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
skip_with_perf_trampoline,
skip_without_pytest_benchmark,
skip_without_valgrind,
xfail_pytest_benchmark_on_pytest_9_2,
)


Expand Down Expand Up @@ -119,6 +120,7 @@ def test_child(self):
)


@xfail_pytest_benchmark_on_pytest_9_2
def test_plugin_disabled(pytester: pytest.Pytester) -> None:
pytester.copy_example("tests/examples/test_addition_fixture.py")
result = pytester.runpytest()
Expand Down Expand Up @@ -191,6 +193,7 @@ def test_another_useless_thing():
)


@xfail_pytest_benchmark_on_pytest_9_2
@skip_without_pytest_benchmark
def test_pytest_benchmark_compatibility(pytester: pytest.Pytester) -> None:
pytester.makepyfile(
Expand Down
Loading