httpx: Windows - Python 3.8+ raises "RuntimeError: Event Loop is closed" on exit.
Checklist
- [ x] The bug is reproducible against the latest release and/or
master. - [ x] There are no similar issues or pull requests to fix it yet.
Describe the bug
I get the following traceback when running the attached code
404
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000017C63D5E310>
Traceback (most recent call last):
File "C:\Python\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "C:\Python\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Python\Python38\lib\asyncio\base_events.py", line 715, in call_soon
self._check_closed()
File "C:\Python\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
To reproduce
async def testing():
client = httpx.AsyncClient()
response = await client.get("https://www.google.com/")
await client.aclose()
print(response.status_code)
async def main():
await testing()
asyncio.run(main())
Inserting time.sleep(0.1) at the end of main() fixes it. Possibly due to the same reasons in the issues linked below.
Environment
- Windows 10 64bit
- Python version: 3.8.1
- HTTPX version 0.12.1
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 23
- Comments: 42 (21 by maintainers)
Links to this issue
Commits related to this issue
- 🐛 fix: asyncio eventloop policy issue on Windows also see: https://github.com/encode/httpx/issues/914#issuecomment-622586610 — committed to yutto-dev/yutto by SigureMo 3 years ago
- fix(outlook): Попытка исправить ошибку «Asyncio Event Loop is Closed» Спорадическая ошибка. Не уверен, что лечение помогает, но попробовать нужно. Инструкция здесь: https://github.com/encode/httpx/is... — committed to gmaFFFFF/extract-order by gmaFFFFF 4 months ago
The workaround is to use the selector event loop like this:
The following from the documentation will not resolve this issue (for some reason):
I ran some tests:
Test against
https://github.com/Sync client works fine:
results:
Async client, run with
asyncio,results:
Async client, run with
trio, works fine:results:
Test against
https://login.microsoftonline.com/Run with sync client
results:
requests always succeed, httpx *sometimes* failed with `ConnectTimeout`
Running with
asyncioresults in three different types error(in an abritary way):
Error 1: Request succeed but with RuntimeError
Error 2: ConnectTimeout
Error 3: ReadTimeout
Run with trio
Sometimes succeed, sometimes failed with `ReadTimeout` or `ConnectTimeout`
ReadTimeout:
ConnectTimeout:
Using:
This problem also occurs on linux.
Have you considered switching to recent version of python?
@Mennaruuk - Ah yup. Just looked though this thread and reminded myself of the comment here.
This is a bug in Python’s stdlib with Windows. See: https://bugs.python.org/issue39232
One option here might be to check if the ProactorEventLoop is the default, and warn if it is.
Nope, it works pretty well for me. I get
<Response [301 Moved Permanently]>with and without HTTPS. I looked at this proposed solution, and I modified it as the following. It worked for me, not sure if it works for others. but I stopped getting the RuntimeError:@WoLpH 👋 Are you able to confirm if HTTPCore 0.12.3 makes the issue go away if you remove that sleep(1) workaround?
It might be related to some recent improvements in HTTPCore (especially some related to socket management).
Is anyone else able to confirm whether this seems resolved using the versions above?
I used to have this issue too. But surprisingly, this issue no longer occurs in any of my projects. I have tested it few times on Python
3.8.6and Python3.9.1. I think this issue can be closed for now.Versions:
Edit: Os version
To do the test, I’ve installed Python from https://www.python.org/ftp/python/3.8.5/python-3.8.5.exe (it wasn’t installed before), and just
pip install httpx[http2]pip freeze shows
I think a test from someone else would be helpful.
Using:
I have a
httpx._exceptions.ConnectTimeouteven withtimeout=60orhttp2=True.I assume this is yet another strange issue with asyncio’s stream.close() - it schedules the closing of the socket but it’s not guaranteed to be done once client.aclose finishes, which means the socket is actually deleted upon garbage collection, and by then I suppose the event loop is already closed… The sleep() call fixed this because it allows asyncio to execute the close callback before proceeding to shutdown the async environment.
See also #825 for more discussion on a possibly related issue.
Have you tried running this on Python 3.8.2?