You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RunTimeError: got Future <Future pending> attached to a different loop when using custom loop in sync fixtures when upgrading from 0.14.2 to 0.15.0 #1315
The bug is reproducible against the latest release and/or master.
There are no similar issues or pull requests to fix it yet.
Describe the bug
Upgrading starlette>=0.15.0 breaks current testing strategy. The setup is mocking a nats subscription by actually using the nats server.
The code works with starlette 0.14.2, upgradign to 0.15.0 gives RunTumeError got Future <Future pending> attached to a different loop . When upgrading to starlette 0.16.0 it gives TimeOut errors. I would love to keep tests sync.
To reproduce
requirements.txt
starlette
requests
pytest
asyncio-nats-client
code
fromstarlette.routingimportRoutefromstarlette.testclientimportTestClientimportpytestfromstarlette.applicationsimportStarlettefromstarlette.responsesimportPlainTextResponseimportasynciofromnats.aio.clientimportClientasNATS"""Test work with starlette 0.14.2Error with starlette 0.15.0: RunTimeError: got Future <Future pending> attached to a different loopError with starlette 0.16.0: Nats timeoutThe test is that the client code makes a nats request to a mocked nats service over nats itself.Requirement a running nats server `docker run -d -p 4222:4222 nats:latest`"""HOST_NATS="localhost:4222"# =======================================================================# CODE# =======================================================================defcreate_app():
asyncdefindex(request):
r=awaitrequest.app.state.nc.request("subject1", timeout=1, payload=b"PING")
returnPlainTextResponse(content=r.data.decode())
asyncdefsetup() ->None:
awaitapp.state.nc.connect(HOST_NATS)
print("Connected to nats")
app=Starlette(debug=True, routes=[Route('/', index)], on_startup=[setup])
app.state.nc: NATS=NATS()
returnappapp=create_app()
# =======================================================================# MOCKS & TESTS# =======================================================================classNatsServiceMock:
def__init__(self) ->None:
self.nc: NATS=NATS()
asyncdeflifespan(self) ->None:
awaitself.nc.connect(HOST_NATS)
awaitself.nc.subscribe("subject1", cb=self.handle)
asyncdefhandle(self, msg):
awaitself.nc.publish(msg.reply, b"PONG")
def__enter__(self):
loop=asyncio.get_event_loop()
loop.run_until_complete(self.lifespan())
returnselfdef__exit__(self, *args) ->None:
pass@pytest.fixture(scope="session")defnats_service() ->None:
withNatsServiceMock() asnc:
yieldnc@pytest.fixture(scope="session")deftest_app(nats_service) ->None:
withTestClient(create_app()) asclient:
yieldclient# =======================================================================# TESTS# =======================================================================deftest_index_should_give_a_succesful_response(test_app):
r=test_app.get("/")
assertr.status_code==200assertr.text=="PONG"
Run:
pytest <file>
Expected behavior
The test to work.
Actual behavior
Test does not work.
Debugging material
output running with starlette 0.15.0:
try:
# wait until the future completes or the timeout
try:
> await waiter
E RuntimeError: Task <Task pending name='anyio.from_thread.BlockingPortal._call_func' coro=<BlockingPortal._call_func() running at /home/sevaho/.local/share/virtualenvs/testje-KTUsWEz0/lib/python3.8/site-packages/anyio/from_thread.py:177> cb=[TaskGroup._spawn.<locals>.task_done() at /home/sevaho/.local/share/virtualenvs/testje-KTUsWEz0/lib/python3.8/site-packages/anyio/_backends/_asyncio.py:622]> got Future <Future pending> attached to a different loop
/usr/lib/python3.8/asyncio/tasks.py:481: RuntimeError
output when running with starlette 0.16.0:
# Wait for the response or give up on timeout.
try:
msg = await asyncio.wait_for(future, timeout, loop=self._loop)
return msg
except asyncio.TimeoutError:
del self._resp_map[token.decode()]
future.cancel()
> raise ErrTimeout
E nats.aio.errors.ErrTimeout: nats: Timeout
/home/sevaho/.local/share/virtualenvs/testje-KTUsWEz0/lib/python3.8/site-packages/nats/aio/client.py:945: ErrTimeout
Environment
OS: Linux
Python version: 3.8
Starlette version: 0.14.2 / 0.15.0 / 0.16.0
Additional context
Important
We're using Polar.sh so you can upvote and help fund this issue.
We receive the funding once the issue is completed & confirmed by you.
Thank you in advance for helping prioritize & fund our backlog.
Checklist
master.Describe the bug
Upgrading starlette>=0.15.0 breaks current testing strategy. The setup is mocking a nats subscription by actually using the nats server.
The code works with starlette 0.14.2, upgradign to 0.15.0 gives
RunTumeError got Future <Future pending> attached to a different loop. When upgrading to starlette 0.16.0 it gives TimeOut errors. I would love to keep tests sync.To reproduce
requirements.txt
code
Run:
Expected behavior
The test to work.
Actual behavior
Test does not work.
Debugging material
output running with starlette 0.15.0:
output when running with starlette 0.16.0:
Environment
Additional context
Important