httpx
httpx copied to clipboard
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
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?
Also: May well be specific to Window's Proactor event loop.
Yes, definitely looks like a Windows specific issue to me - the linked issues are for Windows too.
@florimondmanca , yes upgraded to 3.8.2 to check, the result is the same.
Can confirm this is an issue with the latest PyPi version of aiohttp and Python 3.8.2 on Windows.
Okay, thank you.
I personally don’t have a Windows machine so help with investigation and possible fixes would help.
Would we need to consider black magic such as https://github.com/aio-libs/aiohttp/issues/1925#issuecomment-592596034? How about https://github.com/aio-libs/aiohttp/pull/3733?
FYI this is likely to be something to address on the HTTPCore side, as connection management and networking is done there. Might then be helpful to first come up with a minimal repro example using HTTPCore only?
It'd also be helpful to try switching to using SelectorEventLoop and let us know what the behaviour is like then... https://docs.python.org/3/library/asyncio-eventloop.html#event-loop-implementations (Or to try with Python 3.7 or earlier)
Python only switched the default event loop to proactor from 3.8 onwards. https://docs.python.org/3/library/asyncio-policy.html#asyncio.DefaultEventLoopPolicy
not sure there's a link and can't remember why now but in uvicorn we force the SelectorEventLoop to be the default for windows
Le ven. 1 mai 2020 à 10:23 AM, Tom Christie [email protected] a écrit :
It'd also be helpful to try switching to using SelectorEventLoop and let us know what the behaviour is like then... https://docs.python.org/3/library/asyncio-eventloop.html#event-loop-implementations (Or to try with Python 3.7 or earlier)
Python only switched the default event loop to proactor from 3.8 onwards. https://docs.python.org/3/library/asyncio-policy.html#asyncio.DefaultEventLoopPolicy
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/encode/httpx/issues/914#issuecomment-622297443, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAINSPTJI3OZEDU6VKCF2KLRPKBHTANCNFSM4MVRF2GQ .
The workaround is to use the selector event loop like this:
import sys
import asyncio
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
The following from the documentation will not resolve this issue (for some reason):
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
Same as with #825 - Haven't looked into how awkward it is to do, but really I think we'd want to monkeypatch asyncio's socket unwrapping behaviour, so that we can reliably call .wait_closed(...) without it potentially hanging.
Can anyone on Windows, running Python 3.8+ confirm what currently happens when running this?...
import httpx
import asyncio
async def main():
async with httpx.AsyncClient() as client:
r = await client.get("https://login.microsoftonline.com/")
print(r)
asyncio.run(main(), debug=True)
Trying to verify if we're still exposed to this issue. (I guess we are but 🤷♂️)
Using:
- Windows 10 64bit
- Python 3.8.5
- httpx 0.14.1
I have a httpx._exceptions.ConnectTimeout even with timeout=60 or http2=True.
@dalf - Thanks!
Also uh... that's not at all what I was expecting / looking for. 🙃🙃🙃
Does that replicate on other URLs?...
"https://www.google.com/""https://www.example.org/"
Does removing the debug=True change anything?
Does it work okay in the sync version?...
import httpx
def main():
with httpx.Client() as client:
r = client.get("https://login.microsoftonline.com/")
print(r)
main()
Or with trio?... (Use pip install trio)
import httpx
import trio
async def main():
async with httpx.AsyncClient() as client:
r = await client.get("https://login.microsoftonline.com/")
print(r)
trio.run(main)
Maybe my report is irrelevant, I'm not familiar with the Python Windows environment:
import httpx
import requests
r_requests = requests.get('https://www.google.com')
r_httpx = httpx.get('https://www.google.com')
- requests returns a normal response
- httpx
raises ConnectTimeout: _ssl.c:1106: The handshake operation timed out - the aiohttp client example works (on https://www.google.com )
🤨
That's pretty relevant. But just super surprising.
Are you able to double double check you've got fully up to date httpx and httpcore versions installed? Is anyone else able to confirm?
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
httpcore==0.10.2
httpx==0.14.1
I think a test from someone else would be helpful.
I ran some tests:
Test against https://github.com/
Sync client works fine:
import httpx
import requests
resp = httpx.get('https://github.com/')
print('httpx', resp)
resp = requests.get('https://github.com/')
print('requests', resp)
results:
httpx <Response [200 OK]>
requests <Response [200]>
Async client, run with asyncio,
import httpx
import asyncio
async def main():
async with httpx.AsyncClient() as client:
r = await client.get("https://github.com/")
print(r)
asyncio.run(main(), debug=True)
results:
<Response [200 OK]>
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000024774DEA0D0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Async client, run with trio, works fine:
import httpx
import trio
async def main():
async with httpx.AsyncClient() as client:
r = await client.get("https://github.com/")
print(r)
trio.run(main)
results:
<Response [200 OK]>
Test against https://login.microsoftonline.com/
Run with sync client
import httpx
import requests
resp = httpx.get('https://login.microsoftonline.com/')
print('httpx', resp)
resp = requests.get('https://login.microsoftonline.com/')
print('requests', resp)
results:
requests always succeed, httpx *sometimes* failed with `ConnectTimeout`
requests <Response [200]>
Traceback (most recent call last):
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 342, in map_exceptions
yield
File "e:\projects\pycharm\httpx\httpx\_client.py", line 798, in _send_single_request
) = transport.request(
File "e:\projects\pycharm\httpcore\httpcore\_sync\connection_pool.py", line 188, in request
response = connection.request(
File "e:\projects\pycharm\httpcore\httpcore\_sync\connection.py", line 83, in request
self.socket = self._open_socket(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_sync\connection.py", line 104, in _open_socket
return self.backend.open_tcp_stream(
File "e:\projects\pycharm\httpcore\httpcore\_backends\sync.py", line 144, in open_tcp_stream
return SyncSocketStream(sock=sock)
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpcore\httpcore\_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ConnectTimeout: _ssl.c:1106: The handshake operation timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\sync.py", line 12, in <module>
resp = httpx.get(url)
File "e:\projects\pycharm\httpx\httpx\_api.py", line 174, in get
return request(
File "e:\projects\pycharm\httpx\httpx\_api.py", line 89, in request
return client.request(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 673, in request
return self.send(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 703, in send
response = self._send_handling_redirects(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 732, in _send_handling_redirects
response = self._send_handling_auth(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 769, in _send_handling_auth
response = self._send_single_request(request, timeout)
File "e:\projects\pycharm\httpx\httpx\_client.py", line 792, in _send_single_request
(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 359, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ConnectTimeout: _ssl.c:1106: The handshake operation timed out
Running with asyncio
import httpx
import asyncio
async def main():
async with httpx.AsyncClient() as client:
r = await client.get("https://login.microsoftonline.com/")
print(r)
asyncio.run(main(), debug=True)
results in three different types error(in an abritary way):
Error 1: Request succeed but with RuntimeError
<Response [200 OK]>
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001AB2649A0D0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001AB2649A0D0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Error 2: ConnectTimeout
Traceback (most recent call last):
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 342, in map_exceptions
yield
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1402, in _send_single_request
) = await transport.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection_pool.py", line 188, in request
response = await connection.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 83, in request
self.socket = await self._open_socket(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 104, in _open_socket
return await self.backend.open_tcp_stream(
File "e:\projects\pycharm\httpcore\httpcore\_backends\auto.py", line 40, in open_tcp_stream
return await self.backend.open_tcp_stream(
File "e:\projects\pycharm\httpcore\httpcore\_backends\asyncio.py", line 240, in open_tcp_stream
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpcore\httpcore\_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ConnectTimeout
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\async_test.py", line 13, in <module>
asyncio.run(main(), debug=True)
File "D:\Programs\Python38\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File ".\async_test.py", line 10, in main
r = await client.get("https://login.microsoftonline.com/")
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1441, in get
return await self.request(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1274, in request
response = await self.send(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1305, in send
response = await self._send_handling_redirects(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1334, in _send_handling_redirects
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1371, in _send_handling_auth
response = await self._send_single_request(request, timeout)
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1396, in _send_single_request
(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 359, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ConnectTimeout
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001E4DAFBA0D0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 108, in close
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
RuntimeError: Event loop is closed
Error 3: ReadTimeout
Traceback (most recent call last):
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 342, in map_exceptions
yield
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1402, in _send_single_request
) = await transport.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection_pool.py", line 188, in request
response = await connection.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 96, in request
return await self.connection.request(method, url, headers, stream, timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 73, in request
) = await self._receive_response(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 130, in _receive_response
event = await self._receive_event(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 160, in _receive_event
data = await self.socket.read(self.READ_NUM_BYTES, timeout)
File "e:\projects\pycharm\httpcore\httpcore\_backends\asyncio.py", line 134, in read
return await asyncio.wait_for(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpcore\httpcore\_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ReadTimeout
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\async_test.py", line 13, in <module>
asyncio.run(main(), debug=True)
File "D:\Programs\Python38\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File ".\async_test.py", line 10, in main
r = await client.get("https://login.microsoftonline.com/")
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1441, in get
return await self.request(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1274, in request
response = await self.send(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1305, in send
response = await self._send_handling_redirects(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1334, in _send_handling_redirects
response = await self._send_handling_auth(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1371, in _send_handling_auth
response = await self._send_single_request(request, timeout)
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1396, in _send_single_request
(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 359, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ReadTimeout
Fatal error on SSL transport
protocol: <asyncio.sslproto.SSLProtocol object at 0x00000222F9D43310>
transport: <_ProactorSocketTransport fd=372 read=<_OverlappedFuture cancelled created at D:\Programs\Python38\lib\asyncio\windows_events.py:461>>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 685, in _process_write_backlog
self._transport.write(chunk)
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 359, in write
self._loop_writing(data=bytes(data))
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 395, in _loop_writing
self._write_fut = self._loop._proactor.send(self._sock, data)
AttributeError: 'NoneType' object has no attribute 'send'
Exception ignored in: <function _SSLProtocolTransport.__del__ at 0x00000222F9D02DC0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 322, in __del__
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 317, in close
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 594, in _start_shutdown
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 599, in _write_appdata
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 707, in _process_write_backlog
File "D:\Programs\Python38\lib\asyncio\sslproto.py", line 721, in _fatal_error
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 151, in _force_close
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x00000222F9D6A0D0>
Traceback (most recent call last):
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
File "D:\Programs\Python38\lib\asyncio\proactor_events.py", line 108, in close
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 719, in call_soon
File "D:\Programs\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
RuntimeError: Event loop is closed
Run with trio
Sometimes succeed, sometimes failed with `ReadTimeout` or `ConnectTimeout`
ReadTimeout:
Traceback (most recent call last):
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 342, in map_exceptions
yield
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1402, in _send_single_request
) = await transport.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection_pool.py", line 188, in request
response = await connection.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 96, in request
return await self.connection.request(method, url, headers, stream, timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 73, in request
) = await self._receive_response(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 130, in _receive_response
event = await self._receive_event(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\http11.py", line 160, in _receive_event
data = await self.socket.read(self.READ_NUM_BYTES, timeout)
File "e:\projects\pycharm\httpcore\httpcore\_backends\trio.py", line 63, in read
return await self.stream.receive_some(max_bytes=n)
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpcore\httpcore\_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ReadTimeout
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\async_test-trio.py", line 12, in <module>
trio.run(main)
File "D:\Programs\Python38\lib\site-packages\trio\_core\_run.py", line 1896, in run
raise runner.main_task_outcome.error
File ".\async_test-trio.py", line 9, in main
r = await client.get("https://login.microsoftonline.com/")
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1441, in get
return await self.request(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1274, in request
response = await self.send(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1305, in send
response = await self._send_handling_redirects(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1334, in _send_handling_redirects
response = await self._send_handling_auth(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1371, in _send_handling_auth
response = await self._send_single_request(request, timeout)
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1396, in _send_single_request
(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 359, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ReadTimeout
ConnectTimeout:
Traceback (most recent call last):
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 342, in map_exceptions
yield
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1402, in _send_single_request
) = await transport.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection_pool.py", line 188, in request
response = await connection.request(
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 83, in request
self.socket = await self._open_socket(timeout)
File "e:\projects\pycharm\httpcore\httpcore\_async\connection.py", line 104, in _open_socket
return await self.backend.open_tcp_stream(
File "e:\projects\pycharm\httpcore\httpcore\_backends\auto.py", line 40, in open_tcp_stream
return await self.backend.open_tcp_stream(
File "e:\projects\pycharm\httpcore\httpcore\_backends\trio.py", line 168, in open_tcp_stream
return SocketStream(stream=stream)
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpcore\httpcore\_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ConnectTimeout
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\async_test-trio.py", line 12, in <module>
trio.run(main)
File "D:\Programs\Python38\lib\site-packages\trio\_core\_run.py", line 1896, in run
raise runner.main_task_outcome.error
File ".\async_test-trio.py", line 9, in main
r = await client.get("https://login.microsoftonline.com/")
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1441, in get
return await self.request(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1274, in request
response = await self.send(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1305, in send
response = await self._send_handling_redirects(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1334, in _send_handling_redirects
response = await self._send_handling_auth(
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1371, in _send_handling_auth
response = await self._send_single_request(request, timeout)
File "e:\projects\pycharm\httpx\httpx\_client.py", line 1396, in _send_single_request
(
File "D:\Programs\Python38\lib\contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "e:\projects\pycharm\httpx\httpx\_exceptions.py", line 359, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ConnectTimeout
Using:
- Windows 10 64bit
- Python 3.8.5
- httpx latest master branch
- httpcore latest master branch
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.6 and Python 3.9.1. I think this issue can be closed for now.
Versions:
httpx==0.16.1
- certifi [required: Any, installed: 2020.12.5]
- httpcore [required: ==0.12.*, installed: 0.12.3]
- h11 [required: ==0.*, installed: 0.12.0]
- sniffio [required: ==1.*, installed: 1.2.0]
- rfc3986 [required: >=1.3,<2, installed: 1.4.0]
- sniffio [required: Any, installed: 1.2.0]
Edit: Os version
Version Windows 10 Pro
Version 20H2
Compilation 19042.746
Features Windows Feature Experience Pack 120.2212.551.0
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?
It might be related to some recent improvements in HTTPCore
I have ran some tests.
Error raises on these versions of HTTPCore: 0.12.0, 0.12.1 and 0.12.2
I can do a pull request with fixed requirements.
Coolio. The likely series of events is that prior to 0.12.2, we were scheduling the closing of sockets on the event loop but not awaiting, which might have caused closing to happen after event loop closure on Windows for some reason. On 0.12.3 we are now properly waiting for sockets to close whenever possible.
Thanks for the PR proposition but I guess we can just have existing users upgrade rather than update our pin and issue a new release of HTTPX.
While certainly not a fix, this has worked for me in many cases:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.run_until_complete(asyncio.sleep(1))
loop.close()
@WoLpH 👋 Are you able to confirm if HTTPCore 0.12.3 makes the issue go away if you remove that sleep(1) workaround?
Yes, it solves the issue :)
I still think the workaround can be useful for people though. There are many scenarios where this is an issue from my experience
Nice. I'll close this off now then. Thanks all!
Also: May well be specific to Window's Proactor event loop.
I am experiencing this as well for anyone reading this in posterity, Windows 10 getting the event loop already closed error. The code terminates normally on Linux.
All -
I am seeing the same issue on Windows. The time.sleep(1) has fixed the problem thank you @rmawatson - this has been driving me crazy.
When I tried workarounds such as the one here, what happened was that at the end of the loop, Python exited. And that was it. Even when I have code after the loop, it didn't care about it and just terminated everything. Unfortunately, the time.sleep(10) trick didn't work, and neither did this solution.
Are there any other workarounds? Thank you.
https://user-images.githubusercontent.com/52135169/152754459-16ca58f5-e602-4ae3-bbf0-692d4ee53c29.mp4
@Mennaruuk (or anyone else seeing this) - Let's take this from the start.
- What's the simplest possible script you can show us, that demonstrates the issue.
- What's the exact behaviour/traceback you're seeing?
- Which version of Python are you using?
- Which versions of
httpxandhttpcoredo you have installed?