fix: suppress GeneratorExit during client cleanup #1856
+183
−20
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.

Motivation and Context
In integrating latest llama-stack with MCP examples via OpenAI Responses API, I ran into a couple glitches which broke requests. I narrowed them down to
GeneratorExithandling. When rebuilding llama-stack against this branch all scenarios pass.I noticed this also fixes #1214 which was closed due to missing tests. This adds them.
The Problem
Scenario 1: GC cleanup leaks GeneratorExit
When garbage collector cleans up an orphaned generator while a background task has failed:
Background:
Scenario 2: User TaskGroup wraps GeneratorExit
When user code has a generator yielding inside a TaskGroup:
Background:
except*can break@trio.as_safe_channelcleanup python-trio/trio#3324 - why except* breaks generator cleanupThe Fix
Two exception handlers at the yield point handle both scenarios:
Changes
GeneratorExitandBaseExceptionGrouphandling insse_clientandstreamable_http_clientexceptiongroup>=1.0.0as conditional dependency for Python 3.10 supportread_streamin finally blockHow Has This Been Tested?
Parameterized tests in
tests/client/test_resource_cleanup.py(each runs for both SSE and Streamable HTTP):test_generator_exit_on_gc_cleanup[sse/streamable]- Scenario 1: GC cleanuptest_generator_exit_in_exception_group[sse/streamable]- Scenario 2:BaseExceptionGroup([GeneratorExit])test_generator_exit_mixed_group[sse/streamable]- Scenario 2:BaseExceptionGroup([GeneratorExit, ValueError])Breaking Changes
None
Types of changes
Checklist