python
runtime_error
ai_generated
true
RuntimeError: Event loop is closed pytest.PytestUnhandledThreadExceptionWarning: Exception in thread Thread-1
ID: python/pytest-asyncio-event-loop-closed
80%Fix Rate
85%Confidence
0Evidence
2024-07-08First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 0.23 | active | — | — | — |
Root Cause
pytest-asyncio creates a new event loop per test by default, but aiohttp/httpx AsyncClient or background tasks hold references to the previous loop. When teardown closes the loop, pending callbacks fire against a closed loop.
generic中文
pytest-asyncio 默认每个测试创建一个新的事件循环,但 aiohttp/httpx AsyncClient 或后台任务保留了对先前循环的引用。当 teardown 关闭该循环时,待处理的回调会在已关闭的循环上触发。
Workarounds
-
90% success
# conftest.py import pytest import asyncio @pytest.fixture(scope='session') def event_loop(): loop = asyncio.new_event_loop() yield loop loop.close() -
92% success
@pytest.fixture async def client(): async with httpx.AsyncClient() as c: yield c await c.aclose() -
88% success
# pyproject.toml [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "session"
Dead Ends
Common approaches that don't work:
-
90% fail
Nested event loops raise RuntimeError: asyncio.run() cannot be called from a running event loop when pytest-asyncio already created one.
-
75% fail
Mode changes fixture discovery, not loop lifecycle; the underlying resource leak still closes loops mid-flight.