Repository navigation
Stop wrapped-fixture unwrapping at mock-like objects - #15283
RonnyPfannschmidt wants to merge 4 commits into
Conversation
Fixes #15281. `_find_wrapped_fixture_def` used `inspect.unwrap`, whose depth limit is `sys.getrecursionlimit()`. `unittest.mock.call` returns a new `_Call` for every attribute, including `__wrapped__`, and slipped through the mock guard because its `_mock_name` is `None`. With a raised recursion limit, collection walked that chain until it exhausted memory. - Treat any `_mock_name` attribute as a mock by using `NOTSET` as the sentinel instead of `None`. - Walk `__wrapped__` with a local loop capped at 100 steps, with id-based loop detection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GZsRF9tm1CrxGUNz1r4UC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GZsRF9tm1CrxGUNz1r4UC
|
I haven't reviewed 264846d but it seems pretty complex, and this seems to make it even more complex. Have you considered reverting the change instead? 9.2.0 is still new so I think a revert would be fine. |
|
i'd prefer keeping - i checking if we can simplify a bit |
Review feedback: the hand-rolled __wrapped__ walk added complexity on top of #13745. Go back to inspect.unwrap and stop it at mock-like objects instead, reusing the _is_mocked check that doctest already uses for the same unittest.mock.call problem (moved to compat so fixtures can share it). This also replaces the _mock_name guard, which missed mock.call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GZsRF9tm1CrxGUNz1r4UC
|
🤖 Written by Claude Opus 5.5 via Claude Code for the pytest maintainers; I prompted it, it did the work, I read it. @bluetech I pushed f68dbb4 as a separate commit so the change is visible. It drops the custom In Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GZsRF9tm1CrxGUNz1r4UC
Requested by Ronny · project thread
🤖 Written by Claude Opus 5.5 via Claude Code for the pytest maintainers; I prompted it, it did the work, I read it.
closes #15281
_find_wrapped_fixture_def(added in #13745) callsinspect.unwrap, whose depth limit issys.getrecursionlimit().unittest.mock.callreturns a new_Callfor every attribute, including__wrapped__, and it got past the mock guard because its_mock_nameisNone. Once a conftest or library raised the recursion limit (to 100 000, for example), collection followed that chain until memory ran out.Changes (after review, see f68dbb4):
inspect.unwrapcall now also stops at mock-like objects, via the_is_mockedcheck thatdoctest.pyalready uses for the samemock.callproblem. This replaces the_mock_nameguard, which missedmock.call._is_mockedmoved from_pytest.doctestto_pytest.compatso both modules can share it.The first commits replaced
inspect.unwrapwith a capped hand-written loop. The later commit drops that loop in favour of the smaller change above.Tests:
mock.callandMock()are not unwrapped.A related, pre-existing case under
--doctest-modulesis tracked separately.Co-authored-bycommit trailers.changelogdirectory.🤖 Generated with Claude Code
https://claude.ai/code/session_014GZsRF9tm1CrxGUNz1r4UC