Skip to content

Conversation

@SamMorrowDrums
Copy link

Summary

This PR fixes #3712 by setting a default elapsed value of timedelta(0) on responses returned from MockTransport.

Problem

When creating a Response with pre-loaded content (e.g., json=..., content=..., text=...), the content is immediately read into _content in the Response's __init__. Later, when the client wraps the response stream with BoundSyncStream/BoundAsyncStream to track elapsed time, the stream is never actually consumed because _content is already set.

This causes a RuntimeError when accessing response.elapsed:

def handler(request):
    return httpx.Response(200, json={"message": "Hello"})

transport = httpx.MockTransport(handler)
with httpx.Client(transport=transport) as client:
    response = client.get("https://example.com/")
    print(response.elapsed)  # RuntimeError: .elapsed accessed before response finished

Solution

Set elapsed = timedelta(0) as a default in MockTransport.handle_request() and handle_async_request() if the response doesn't already have _elapsed set.

This:

  1. Allows users to access response.elapsed without errors
  2. Preserves user-set elapsed values if they manually set it in their handler
  3. Doesn't require boilerplate code in every handler (as suggested in the issue)

Changes

  • Added import datetime to httpx/_transports/mock.py
  • Added default elapsed setting in handle_request() (sync)
  • Added default elapsed setting in handle_async_request() (async)

Testing

Verified that:

  • Existing MockTransport tests pass
  • response.elapsed returns timedelta(0) for pre-loaded responses
  • User-set elapsed values are preserved

When creating a Response with pre-loaded content (e.g., json=...),
the BoundSyncStream is never consumed, so elapsed is never set.
This causes a RuntimeError when accessing response.elapsed.

This fix sets a default elapsed of timedelta(0) if not already set,
allowing users to access response.elapsed without errors while still
preserving any user-set elapsed values.

Fixes encode#3712
@SamMorrowDrums
Copy link
Author

SamMorrowDrums commented Dec 9, 2025

The CI failure appears to be an unrelated flaky network test (test_sync_proxy_close in tests/client/test_proxies.py) that timed out trying to connect to a proxy server:

E   httpx.ReadTimeout: timed out
tests/client/test_proxies.py:118

Test summary: 1 failed, 1416 passed, 1 skipped

This is not related to the MockTransport changes in this PR.

@karpetrosyan
Copy link
Contributor

I'll close this for now until we have a good design decision around it

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.

MockTransport doesn't set the elapsed property

2 participants