Consult nested mocks innermost-first on the httpx backend - #3548
Merged
Conversation
respx keeps every started router in a single process-wide list and tries them in registration order. Each MockVWS router ends with a catch-all, so an outer mock always answered and a nested inner mock was never consulted -- a request to the inner mock's own URL was refused. Move each newly started router to the front of respx's list so nesting resolves innermost-first, as it already does on the requests and httpx2 backends, whose patches form a LIFO stack. Fixes #3544 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
adamtheturtle
temporarily deployed
to
development
September 5, 2026 15:57 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
adamtheturtle
temporarily deployed
to
vuforia
September 5, 2026 16:01 — with
GitHub Actions
Inactive
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3544.
Problem
respxkeeps every started router in a single process-wide list and consults them in registration order. EachMockVWSrespx router ends with a catch-all which raiseshttpx.ConnectError(notAllMockedAssertionError), so it propagates out ofMocker.handler's loop and no later router is tried.The result: with one
MockVWSnested inside another, the outer mock answered and the inner mock was unreachable — a request to the URL the inner mock was created for was refused. Therequestsandhttpx2backends do the opposite, because their patches form a LIFO stack.Fix
start_respx_routernow moves each newly started router to the front ofrespx's router list, so nesting resolves innermost-first on every backend. Unregistering on stop already restores the outer router to the front, so the outer mock answers again once the inner one has stopped.Mocker.async_handlerwalks the same list, so async nesting is fixed too.Test
TestVWS::test_nested_mocksintests/mock_vws/test_respx_mock_usage.py, mirroring the existinghttpx2test of the same name.🤖 Generated with Claude Code