I am trying to use the asyncpraw library, but I get RuntimeError: Event loop is closed
.
This is my code and traceback.
Code
import asyncio
import asyncpraw
async def main():
reddit = asyncpraw.Reddit('praw_ini_name')
print('User is', await reddit.user.me())
await reddit.close()
asyncio.run(main())
Traceback
User is python_user
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000021D2898C1F0>
Traceback (most recent call last):
File "C:\Program Files\Python39\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "C:\Program Files\Python39\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Program Files\Python39\lib\asyncio\base_events.py", line 746, in call_soon
self._check_closed()
File "C:\Program Files\Python39\lib\asyncio\base_events.py", line 510, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
This however does not happen (no exceptions) if I start the event loop like so
import asyncio
import asyncpraw
async def main():
reddit = asyncpraw.Reddit('praw_ini_name')
print('User is', await reddit.user.me())
await reddit.close()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
I am under the assumption that in newer python versions the preferred way to start an event loop is the way I have shown in the first snippet, so why does that not work? Even though it prints the output, why is my code throwing an exception?
I am on Python 3.9.2, with asyncpraw
7.2.0.
I have seen Asyncio Event Loop is Closed, Python3.x RuntimeError: Event loop is closed and Aiohttp, Asyncio: RuntimeError: Event loop is closed and I believe they are not dupes. My question asks why it works with one but not the other.
If I do not use reddit.close()
I get the following
User is python_user
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000025BAAAEF8B0>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x0000025BAAAF1640>, 174448.968)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000025BAAAEFA90>
Thank You.
asyncio.run
explicity closes the loop on completion.
asyncio.run(coro, *, debug=False)
[...]
This function always creates a new event loop and closes it at the end.
This means the event loop is not available for cleanup once main
finishes. Cleanup must instead be done deterministically, via async generators, or synchronously.
When managing the loop manually and not calling loop.close()
, the loop remains available to schedule cleanup callbacks. Be aware that this does not necessarily mean cleanup is actually run unless the loop is explicitly resumed.
The problem in specific is a known issue with aiohttp 3.x.