Ensure all async generators are explicitly closed
Merged
KL
6mo ago+160+160+012345678901234567890123456789-90-90-01234567890123456789
Summary
Backports encode/httpcore#1019 by @agronholm into our vendored src/httpcore/.
The upstream PR wraps async for iterations over request/response body streams in a safe_async_iterate() helper that explicitly calls aclose() in a try/finally, rather than relying on the GC.
Under trio this surfaced for us as test_write_timeout[trio] failing with PytestUnraisableExceptionWarning: Exception ignored in: <async_generator object ByteStream.__aiter__> during teardown. The exception was the body iterator being garbage-collected after the timeout aborted the request, with the trio event loop already torn down.
Test plan
-
uv run pytestā 1417 passed, 1 skipped, 0 failed (was 1416 passed, 1 failed) -
tests/test_timeouts.py::test_write_timeout[trio]now passes - CI green on all Python versions
AI Disclaimer
This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.