Skip to content

fix: support pytest 9.2 fixture manager changes - #141

Open
claude[bot] wants to merge 3 commits into
masterfrom
fix/pytest-9.2-fixture-override
Open

claude[bot] wants to merge 3 commits into
masterfrom
fix/pytest-9.2-fixture-override

Conversation

@claude

@claude claude Bot commented Oct 28, 2026

Copy link
Copy Markdown

Requested via Slack thread

Before: with pytest 9.2 and pytest-benchmark installed, pytest --codspeed crashes at session start with AttributeError: 'FixtureManager' object has no attribute '_arg2fixturedefs'. pytest 9.2 replaced that private attribute with _arg2node2fixturedefs (pytest-dev/pytest#14984, fixing pytest-dev/pytest#14942), and our pytest_plugin_registered hook wrote into it to swap pytest-benchmark's benchmark fixture for ours.

After: on pytest 9.1+, codspeed's benchmark fixture is registered through the public pytest.register_fixture API in a trylast pytest_sessionstart hook, at session level, so it takes precedence over the one from pytest-benchmark/pytest-speed. --codspeed runs pass on pytest 9.2.

How:

  • The new path is feature-detected (HAS_PYTEST_REGISTER_FIXTURE = hasattr(pytest, "register_fixture")), so it covers 9.1 as well as 9.2 rather than only 9.2. Using the public API wherever it exists means one less private-attribute dependency to break again. If you'd prefer to keep 9.1 on the old path and only switch on 9.2, that's a one-line change to the condition.
  • On pytest < 9.1, the previous _arg2fixturedefs swap is kept unchanged as the fallback.
  • pytest-benchmark itself is still broken on pytest 9.2 when used without --codspeed: it reads the removed Node._nodeid in pytest_benchmark/fixture.py (still the case in pytest-benchmark 5.3.0). test_plugin_disabled and test_pytest_benchmark_compatibility run pytest-benchmark without --codspeed, so they are marked xfail(strict=False) only when pytest >= 9.2 and pytest-benchmark are both installed. Non-strict so they start passing again once pytest-benchmark ships a fix. Happy to switch this to a skip, or to drop it if you'd rather keep those jobs red as a reminder.
  • The CI matrix installs pytest>=8.1.1, which already resolves to 9.2, so CI exercises this path without a matrix change.

Tested locally on Python 3.13 with pytest 8.4.2, 9.1.1 and 9.2.0, each with and without pytest-benchmark (plus pytest-benchmark 5.3.0 on 9.2.0).


Generated by Claude Code

claude and others added 2 commits October 28, 2026 10:33
pytest 9.2 replaced the private `FixtureManager._arg2fixturedefs` with
`_arg2node2fixturedefs` (pytest-dev/pytest#14984). The
`pytest_plugin_registered` hook wrote into `_arg2fixturedefs` to swap
pytest-benchmark's `benchmark` fixture for ours, so every `--codspeed`
run with pytest-benchmark installed crashed with an AttributeError.

On pytest 9.1+, register the override through the public
`pytest.register_fixture` API at session start instead. Older pytest
keeps the previous `_arg2fixturedefs` swap.

pytest-benchmark itself still reads the removed `Node._nodeid` on
pytest 9.2, so the two tests that run it without `--codspeed` are
marked as non-strict xfail on that combination.

Co-Authored-By: Guillaume Lagrange <19265358+GuillaumeLagrange@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…chmark

The matrix only installed the latest pytest, so the fixture override
paths for pytest without register_fixture (9.0) and before 8.1.1 were
never exercised. Add pytest 9.0 and 8.0 jobs on Python 3.15 only, to
avoid the full combinatorial matrix.

The valgrind install condition matched a "pytest-benchmark" config that
no longer exists since the split into -4 and -5, so the valgrind tests
running --codspeed with pytest-benchmark installed were always skipped.

Co-Authored-By: Claude <noreply@anthropic.com>
@GuillaumeLagrange

Copy link
Copy Markdown
Contributor

@art049 FYI, you're much more familiar with pytest-codspeed than I am

@not-matthias not-matthias left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@GuillaumeLagrange
GuillaumeLagrange marked this pull request as ready for review October 28, 2026 11:19
@greptile-apps

greptile-apps Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Uses pytest.register_fixture when available to replace the competing benchmark fixture. Older pytest versions keep the existing private-field fallback.

  • CodSpeed’s benchmark fixture works across newer and older pytest versions.
  • Standalone pytest-benchmark checks are marked as expected failures on affected pytest versions.

Reviews (1) · Last reviewed commit: "ci: test older pytest versions and run v..." · Reviewed by Greptile

@GuillaumeLagrange

Copy link
Copy Markdown
Contributor

CI is stuck, having a look

@codspeed

codspeed Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 1.99%

2 warnings, 1 note

⚠️ 6 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

ℹ️ 21 benchmarks have no flamegraph

The flamegraph wasn't generated: the symbols of the profiling trace could not be resolved, because no information about the language frames was collected.

See affected benchmarks

⚡ 6 improved benchmarks
❌ 2 regressed benchmarks
✅ 241 untouched benchmarks
⏩ 28 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Walltime test_multiprocessing_map[1000] 53.1 ms 131.3 ms -59.57%
❌ Walltime test_solve_maze[maze0] 24.1 µs 25.7 µs -6.33%
⚡ Memory test_multiprocessing_map[100] 4.3 MB 3.4 MB +26.97%
⚡ Memory test_multiprocessing_map[100000] 6.4 MB 5.5 MB +17.62%
⚡ Walltime test_tcp_connection[1.1.1.1-53] 873.5 µs 765.5 µs +14.1%
⚡ Memory test_multiprocessing_map[10000] 3.9 MB 3.6 MB +10.87%
⚡ Memory test_multiprocessing_map[10] 3.5 MB 3.2 MB +10.09%
⚡ Walltime test_sum_of_squares[sum_of_squares_sum_comprehension_power] 241.7 µs 223.5 µs +8.11%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/pytest-9.2-fixture-override (cd4265e) with master (5af4238)

Open in CodSpeed

Footnotes

  1. 28 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Comment thread src/pytest_codspeed/plugin.py Outdated
Comment on lines +436 to +465
if not IS_PYTEST_BENCHMARK_INSTALLED:
def _benchmark_compat(codspeed_benchmark, request: pytest.FixtureRequest):
"""
Compatibility with pytest-benchmark
"""
return codspeed_benchmark

@pytest.fixture(scope="function")
def benchmark(codspeed_benchmark, request: pytest.FixtureRequest):
"""
Compatibility with pytest-benchmark
"""
return codspeed_benchmark

if not IS_PYTEST_BENCHMARK_INSTALLED:
benchmark = pytest.fixture(scope="function", name="benchmark")(_benchmark_compat)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we changing this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@claude why?

Keep the original `benchmark` fixture and `pytest_plugin_registered`
hook untouched, and only add the pytest 9.1+ path: the hook returns
early when `pytest.register_fixture` is available, and a new
`pytest_sessionstart` hook registers the codspeed `benchmark` override
at session level instead.

Co-Authored-By: Arthur Pastel <15641577+art049@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants