Skip to content

Commit f1748a0

Browse files
committed
improve workaround
1 parent 86a377f commit f1748a0

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

tests/shared/test_sse.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
import anyio
66
import httpx
77
import pytest
8+
import sse_starlette
89
from anyio.abc import TaskGroup
910
from inline_snapshot import snapshot
11+
from packaging import version
1012
from pydantic import AnyUrl
11-
from sse_starlette.sse import AppStatus
1213
from starlette.applications import Starlette
1314
from starlette.requests import Request
1415
from starlette.responses import Response
@@ -33,17 +34,40 @@
3334
Tool,
3435
)
3536

37+
SSE_STARLETTE_VERSION = version.parse(sse_starlette.__version__)
38+
NEEDS_RESET = SSE_STARLETTE_VERSION < version.parse("3.0.0")
39+
3640

3741
@pytest.fixture(autouse=True)
3842
def reset_sse_app_status():
3943
"""Reset sse-starlette's global AppStatus singleton before each test.
4044
41-
This is necessary because AppStatus.should_exit_event (a global anyio.Event) gets bound
42-
to one event loop but accessed from others during parallel test execution (xdist workers),
43-
causing RuntimeError("bound to a different event loop"), which prevents the SSE server
44-
from responding (leaving status at 499) and causes ClosedResourceError during teardown.
45+
AppStatus.should_exit_event is a global asyncio.Event that gets bound to
46+
an event loop. This ensures each test gets a fresh Event and prevents
47+
RuntimeError("bound to a different event loop") during parallel test
48+
execution with pytest-xdist.
49+
50+
NOTE: This fixture is only necessary for sse-starlette < 3.0.0.
51+
Version 3.0+ eliminated the global state issue entirely by using
52+
context-local events instead of module-level singletons, providing
53+
automatic test isolation without manual cleanup.
54+
55+
See <https://github.com/sysid/sse-starlette/pull/141> for more details.
4556
"""
46-
AppStatus.should_exit_event = anyio.Event()
57+
if not NEEDS_RESET:
58+
yield
59+
return
60+
61+
# lazy import to avoid import errors
62+
from sse_starlette.sse import AppStatus
63+
64+
# Setup: Reset before test
65+
AppStatus.should_exit_event = anyio.Event() # type: ignore[attr-defined]
66+
67+
yield
68+
69+
# Teardown: Reset after test to prevent contamination
70+
AppStatus.should_exit_event = anyio.Event() # type: ignore[attr-defined]
4771

4872

4973
SERVER_NAME = "test_server_for_SSE"

0 commit comments

Comments
 (0)