-
-
Notifications
You must be signed in to change notification settings - Fork 30.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RuntimeError: await wasn't used with future #106429
Comments
According to the original issue, the problem occurs occasionally during normal use of the app for some users. Breaking SSL is just an easy way to reproduce 100% of the time. |
I'n not comfortable just running the suggested repro, given that the name of the project contains the word "miner". But it seems you are. Could you try disabling the import sys
assert sys.modules.get("_asyncio") is None
sys.modules["_asyncio"] = None If it still fails, that would rule out a bug in the C accelerator module. If it then doesn't fail, we know we have to look in |
I wouldn't base my trust on a project's name. :P I just run everything in a container. The exception happens on startup, before you configure the app to do anything, so you also don't need Twitch credentials or anything to reproduce.
Yes, the issue still reproduces. I can verify that it is now raising from the Python file at: Though still unsure where to look next to figure out what's happening. I assume that somehow, somewhere, a future is getting yielded from a second time even though it's not finished. |
My money is on a bug in the app. |
From traceback: 06:33:25 PM: File "/home/ubuntu/hacking/aiohttp/aiohttp/client.py", line 1103, in send
06:33:25 PM: return self._coro.send(arg) it appears aiohttp is manually sending to coroutine, if you manually manipulate the coroutine then the internal handling break and nothing can be done. |
Hmm, it appears to just be a wrapper around the coroutine. I'm not sure why though. As far as I can see, aiohttp doesn't call the method itself.. https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py#L1096 |
Together with @guihkx, we've found this to be the smallest working repro: import asyncio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
try:
response = await asyncio.ensure_future(session.get('https://www.google.com/'))
print(await response.text())
finally:
response.release()
asyncio.run(main()) This is after setting |
Hmm, doesn't reproduce for me: Traceback (most recent call last):
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 964, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
File "/usr/lib/python3.10/asyncio/base_events.py", line 1064, in create_connection
raise exceptions[0]
File "/usr/lib/python3.10/asyncio/base_events.py", line 1049, in create_connection
sock = await self._connect_sock(
File "/usr/lib/python3.10/asyncio/base_events.py", line 960, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/lib/python3.10/asyncio/selector_events.py", line 499, in sock_connect
return await fut
File "/usr/lib/python3.10/asyncio/selector_events.py", line 504, in _sock_connect
sock.connect(address)
OSError: [Errno 101] Network is unreachable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/ubuntu/desktop/test.py", line 7, in main
response = await asyncio.ensure_future(session.get('https://www.google.com/'))
File "/home/ubuntu/hacking/aiohttp/aiohttp/client.py", line 1106, in throw
self._coro.throw(arg)
File "/home/ubuntu/hacking/aiohttp/aiohttp/client.py", line 511, in _request
conn = await self._connector.connect(
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 517, in connect
proto = await self._create_connection(req, traces, timeout)
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 883, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 1147, in _create_direct_connection
raise last_exc
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 1117, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
File "/home/ubuntu/hacking/aiohttp/aiohttp/connector.py", line 972, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host www.google.com:443 ssl:default [Network is unreachable]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ubuntu/desktop/test.py", line 12, in <module>
asyncio.run(main())
File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/ubuntu/desktop/test.py", line 10, in main
response.release()
UnboundLocalError: local variable 'response' referenced before assignment |
Just providing some extra information I can think of, since it does reproduce on my Arch Linux machine:
Output: $ SSL_CERT_DIR=/dev/null SSL_CERT_FILE=/dev/null python3 main.py
Traceback (most recent call last):
File "/home/gui/dev/aiohttp-repro/main.py", line 7, in main
response = await asyncio.ensure_future(session.get('https://www.google.com/'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/client.py", line 1125, in send
return self._coro.send(arg)
^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/client.py", line 536, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/connector.py", line 540, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/connector.py", line 901, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/connector.py", line 1175, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/env/lib/python3.11/site-packages/aiohttp/connector.py", line 980, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/asyncio/base_events.py", line 1069, in create_connection
sock = await self._connect_sock(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/asyncio/base_events.py", line 973, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/lib/python3.11/asyncio/selector_events.py", line 634, in sock_connect
return await fut
^^^^^^^^^
RuntimeError: await wasn't used with future
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/gui/dev/aiohttp-repro/main.py", line 12, in <module>
asyncio.run(main())
File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/gui/dev/aiohttp-repro/main.py", line 10, in main
response.release()
^^^^^^^^
UnboundLocalError: cannot access local variable 'response' where it is not associated with a value |
As I said earlier this has nothing to do with ssl or anything, you are breaking the handling of coroutine by sending to it manually: import asyncio
async def main():
async def coro():
f = asyncio.Future()
await f
c = coro()
fut = asyncio.ensure_future(c)
c.send(None) # Start the coroutine
# await fut
asyncio.run(main()) This has the same error Task exception was never retrieved
future: <Task finished name='Task-2' coro=<main.<locals>.coro() done, defined at /workspaces/cpython/main.py:4> exception=RuntimeError("await wasn't used with future")>
Traceback (most recent call last):
File "/workspaces/cpython/main.py", line 6, in coro
await f
RuntimeError: await wasn't used with future |
I'm confused. The repro code doesn't have anything that "sends to it manually". Also, I don't get why it breaks when SSL handling is intentionally broken. All of this points to an |
If you look further up the thread, he's referring to a line of code in aiohttp (#106429 (comment)). But, I've no idea how that line actually gets called, I can't see anything that calls it in aiohttp itself, and the code looks like it just wraps a coroutine object, for a reason that probably only @asvetlov knows (if he can even remember from 6 years ago: aio-libs/aiohttp@439c732#diff-f334e752b4894ef951105572ab8b195aeb8db90eb6e48b1dfbd9a01da4c854f5R740). |
With no further information, I'll probably need to spend a day (which I don't have spare right now) breaking that wrapper in order to understand it enough to replace it. So, if nobody has any further ideas, I'll probably close this issue until I've found time to look at that in more depth. |
I am closing this on the basis of my above comment, I'll reopen if you provide further information. |
This seems like a really weird one. Original issue is aio-libs/aiohttp#7117
I can reproduce easily with:
It seems like something must have messed up the loop in some way to cause it to fail at this point.
I believe the exception comes from https://github.com/python/cpython/blob/main/Modules/_asynciomodule.c#L1631
But, I'm not familiar with the C side of things to understand what happened.
An interesting detail is that I played around to try and figure out what was happening, and it doesn't seem to be related to the particular future being awaited on, it must be something that happens before it. I added an
asyncio.sleep()
call just before the future that was giving the error, and now the error occurs inside the sleep() call. Note the sleep() at the end of this traceback:Your environment
The text was updated successfully, but these errors were encountered: