ci: restack Python 3.13 anyio coverage#312
Merged
janhilgard merged 1 commit intowaybarrios:mainfrom Apr 15, 2026
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Author
|
Opened as the requested minimal replacement for #226 on top of current main and re-ran the focused local async validation slice before pushing. |
janhilgard
approved these changes
Apr 15, 2026
Collaborator
janhilgard
left a comment
There was a problem hiding this comment.
+1 from me. Clean, minimal CI change. Agreeing with Thump604's approval.
One small observation: the anyio_backend fixture in conftest.py is now scope="session" which is correct for performance, but worth noting that if trio support is ever added, this will need revisiting (not a concern today since trio is not a dependency).
All 9 CI jobs green, pyproject.toml dev deps are consistent with the CI install. LGTM.
Thump604
added a commit
to Thump604/vllm-mlx
that referenced
this pull request
Apr 16, 2026
The test-apple-silicon runner doesn't have pytest-asyncio installed. Switch TestSseDoneTermination tests from @pytest.mark.asyncio to @pytest.mark.anyio, matching the convention established in waybarrios#312.
Thump604
added a commit
that referenced
this pull request
Apr 18, 2026
* fix(streaming): guarantee data: [DONE] SSE event on all paths Two changes to ensure OpenAI-compatible clients never hang waiting for stream termination: 1. stream_completion: wrap generation loop in try/except/finally so [DONE] is always emitted even if the engine raises mid-stream. 2. _disconnect_guard: catch exceptions from the inner generator's __anext__ and emit [DONE] before breaking. Previously only StopAsyncIteration was caught, so engine errors would propagate without the termination signal. Closes #101 * test: add regression tests for SSE [DONE] termination (#101) Three tests covering the exact behavior #302 guarantees: 1. stream_completion normal path emits exactly one [DONE] at the end 2. stream_completion with mid-stream engine exception still emits [DONE] 3. _disconnect_guard emits [DONE] when inner generator raises Uses FakeEngine/ExplodingEngine pattern consistent with existing test_server.py streaming tests. * fix: make SSE terminal frame endpoint-specific via _ensure_sse_terminal Addresses review feedback: _disconnect_guard() is shared by OpenAI and Anthropic endpoints, so it must not hard-code data: [DONE]. Changes: - Add _ensure_sse_terminal() wrapper that guarantees exactly one protocol-specific terminal frame, even on mid-stream exceptions - Remove data: [DONE] from _disconnect_guard exception handler - Wrap all three streaming call sites: - /v1/completions: data: [DONE] - /v1/chat/completions: data: [DONE] - /v1/messages: event: message_stop Tests: - test_ensure_sse_terminal_normal_no_duplicate: happy path, no double - test_ensure_sse_terminal_exception_emits_done: engine crash → [DONE] - test_ensure_sse_terminal_anthropic_protocol: crash → message_stop, NOT [DONE] All 42 test_server.py tests pass. * fix(test): use anyio marker for Apple Silicon CI compatibility The test-apple-silicon runner doesn't have pytest-asyncio installed. Switch TestSseDoneTermination tests from @pytest.mark.asyncio to @pytest.mark.anyio, matching the convention established in #312. * fix(test): wrap exception test with _ensure_sse_terminal stream_completion() does not catch engine exceptions itself — that is _ensure_sse_terminal()'s responsibility. The test was calling stream_completion() directly without the wrapper, so the RuntimeError propagated instead of being caught and followed by [DONE]. Wrap the test's stream_completion call with _ensure_sse_terminal(), matching how the server routing layer uses it.
arozanov
pushed a commit
to arozanov/vllm-mlx
that referenced
this pull request
Apr 30, 2026
…rios#302) * fix(streaming): guarantee data: [DONE] SSE event on all paths Two changes to ensure OpenAI-compatible clients never hang waiting for stream termination: 1. stream_completion: wrap generation loop in try/except/finally so [DONE] is always emitted even if the engine raises mid-stream. 2. _disconnect_guard: catch exceptions from the inner generator's __anext__ and emit [DONE] before breaking. Previously only StopAsyncIteration was caught, so engine errors would propagate without the termination signal. Closes waybarrios#101 * test: add regression tests for SSE [DONE] termination (waybarrios#101) Three tests covering the exact behavior waybarrios#302 guarantees: 1. stream_completion normal path emits exactly one [DONE] at the end 2. stream_completion with mid-stream engine exception still emits [DONE] 3. _disconnect_guard emits [DONE] when inner generator raises Uses FakeEngine/ExplodingEngine pattern consistent with existing test_server.py streaming tests. * fix: make SSE terminal frame endpoint-specific via _ensure_sse_terminal Addresses review feedback: _disconnect_guard() is shared by OpenAI and Anthropic endpoints, so it must not hard-code data: [DONE]. Changes: - Add _ensure_sse_terminal() wrapper that guarantees exactly one protocol-specific terminal frame, even on mid-stream exceptions - Remove data: [DONE] from _disconnect_guard exception handler - Wrap all three streaming call sites: - /v1/completions: data: [DONE] - /v1/chat/completions: data: [DONE] - /v1/messages: event: message_stop Tests: - test_ensure_sse_terminal_normal_no_duplicate: happy path, no double - test_ensure_sse_terminal_exception_emits_done: engine crash → [DONE] - test_ensure_sse_terminal_anthropic_protocol: crash → message_stop, NOT [DONE] All 42 test_server.py tests pass. * fix(test): use anyio marker for Apple Silicon CI compatibility The test-apple-silicon runner doesn't have pytest-asyncio installed. Switch TestSseDoneTermination tests from @pytest.mark.asyncio to @pytest.mark.anyio, matching the convention established in waybarrios#312. * fix(test): wrap exception test with _ensure_sse_terminal stream_completion() does not catch engine exceptions itself — that is _ensure_sse_terminal()'s responsibility. The test was calling stream_completion() directly without the wrapper, so the RuntimeError propagated instead of being caught and followed by [DONE]. Wrap the test's stream_completion call with _ensure_sse_terminal(), matching how the server routing layer uses it.
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.
Summary
Why
This is the minimal replacement for #226 after #288 landed the test-file conversions. It keeps only the remaining CI/dependency/backend wiring on top of current main.
Local validation
Supersedes the remaining scope of #226.