TestClient
fails to close memory stream objects
#2603
Replies: 7 comments 13 replies
-
This doesn't require multiple from fastapi import APIRouter, FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
router = APIRouter()
@router.post('/api/test')
def route() -> str:
return 'OK'
app.include_router(router)
def test_route():
with TestClient(app) as client:
client.get('/api/test') For some reason,
|
Beta Was this translation helpful? Give feedback.
-
@loichuder, do you mind if we change the subject of this discussion to something simpler, like " |
Beta Was this translation helpful? Give feedback.
-
a somewhat simpler test that often, but not always, reproduces this warning from starlette.applications import Starlette
from starlette.testclient import TestClient
def test_close_warning():
for _ in range(10):
with TestClient(Starlette()) as client:
client.get("/") |
Beta Was this translation helpful? Give feedback.
-
i'm fairly confident this is an issue. i've tracked it down to the async def wait_shutdown(self) -> None:
async def receive() -> typing.Any:
message = await self.stream_send.receive()
if message is None:
self.task.result()
return message
async with self.stream_send:
await self.stream_receive.send({"type": "lifespan.shutdown"})
message = await receive()
assert message["type"] in (
"lifespan.shutdown.complete",
"lifespan.shutdown.failed",
)
if message["type"] == "lifespan.shutdown.failed":
await receive() i recommend this function be changed to the following, to close both streams: async def wait_shutdown(self) -> None:
async def receive() -> typing.Any:
message = await self.stream_send.receive()
if message is None:
self.task.result()
return message
async with self.stream_send, self.stream_receive:
await self.stream_receive.send({"type": "lifespan.shutdown"})
message = await receive()
assert message["type"] in (
"lifespan.shutdown.complete",
"lifespan.shutdown.failed",
)
if message["type"] == "lifespan.shutdown.failed":
await receive() i've verified that this change fixes the issue. |
Beta Was this translation helpful? Give feedback.
-
Now that we have a fix for this, what is the procedure; can we submit a PR with that fix, or do we need an admin to approve something? The Reporting Bugs or Other Issues section fo |
Beta Was this translation helpful? Give feedback.
-
I've encountered the same issue just today but it appears no PR was created so I've created one here PR-2693. Credit to @markwaddle for proposing the solution. @Kludex @jhominal can you please take a look. Thanks. |
Beta Was this translation helpful? Give feedback.
-
I'm still seeing this error when testing fastapi using the following package versions, even with PR-2693 applied:
So there still seem to be cases where this PR is insufficient to close the streams, unfortunately. But I have no idea how to track down the cause. (I also posted this to the PR, but realised that this is a better location.) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
EDIT: My original post below was based on my shallow understanding of the problem. See the comments below by @ppena-LiveData and @markwaddle for better test examples.
An example is worth a thousand words:
When running this with
pytest -W error
, I get the following error:Note that this warning appears with anyio 4.4.0. Also, the warning does not appear when running a single test (which is why multiple
test_app...
are needed)My guess is that the
MemoryObjectReceiveStreams
created there are not properly closed ?Beta Was this translation helpful? Give feedback.
All reactions