From ae40e9829ccde7a501800e3453e99b6fe829bc6f Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Mon, 22 Aug 2022 04:42:27 +0200 Subject: [PATCH] Merge PR #6877 (cherry picked from commit 5bf9b4aae7046704b418c16452c2d1ced934abfb) --- CHANGES/6757.misc | 3 +++ aiohttp/client.py | 2 ++ aiohttp/client_reqrep.py | 15 +++++++++------ aiohttp/connector.py | 10 ++++++++++ aiohttp/test_utils.py | 16 ++++++++++------ 5 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 CHANGES/6757.misc diff --git a/CHANGES/6757.misc b/CHANGES/6757.misc new file mode 100644 index 00000000000..986e3feb95f --- /dev/null +++ b/CHANGES/6757.misc @@ -0,0 +1,3 @@ +Work around the changes in 3.11, e.g. :py:class:`~asyncio.TimeoutError` is an :py:class:`OSError`, +and :py:class:`~unittest.IsolatedAsyncioTestCase` calls :py:function:`~asyncio.set_event_loop` +differently -- by :user:`graingert`. diff --git a/aiohttp/client.py b/aiohttp/client.py index fa630333df6..8ef504af32f 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -566,6 +566,8 @@ async def _request( except ClientError: raise except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise ClientOSError(*exc.args) from exc self._cookie_jar.update_cookies(resp.cookies, resp.url) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index ce55be6e7ff..28b8a28d0d8 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -588,12 +588,15 @@ async def write_bytes( await writer.write_eof() except OSError as exc: - new_exc = ClientOSError( - exc.errno, "Can not write request body for %s" % self.url - ) - new_exc.__context__ = exc - new_exc.__cause__ = exc - protocol.set_exception(new_exc) + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + protocol.set_exception(exc) + else: + new_exc = ClientOSError( + exc.errno, "Can not write request body for %s" % self.url + ) + new_exc.__context__ = exc + new_exc.__cause__ = exc + protocol.set_exception(new_exc) except asyncio.CancelledError as exc: if not conn.closed: protocol.set_exception(exc) diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 85f212f423e..114cceb82f0 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -983,6 +983,8 @@ async def _wrap_create_connection( except ssl_errors as exc: raise ClientConnectorSSLError(req.connection_key, exc) from exc except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise client_error(req.connection_key, exc) from exc def _fail_on_no_start_tls(self, req: "ClientRequest") -> None: @@ -1104,6 +1106,8 @@ async def _start_tls_connection( except ssl_errors as exc: raise ClientConnectorSSLError(req.connection_key, exc) from exc except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise client_error(req.connection_key, exc) from exc except TypeError as type_err: # Example cause looks like this: @@ -1155,6 +1159,8 @@ def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: host_resolved.add_done_callback(drop_exception) raise except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise # in case of proxy it is not ClientProxyConnectionError # it is problem of resolving proxy ip itself raise ClientConnectorError(req.connection_key, exc) from exc @@ -1373,6 +1379,8 @@ async def _create_connection( self._factory, self._path ) except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise UnixClientConnectorError(self.path, req.connection_key, exc) from exc return cast(ResponseHandler, proto) @@ -1438,6 +1446,8 @@ async def _create_connection( # other option is to manually set transport like # `proto.transport = trans` except OSError as exc: + if exc.errno is None and isinstance(exc, asyncio.TimeoutError): + raise raise ClientConnectorError(req.connection_key, exc) from exc return cast(ResponseHandler, proto) diff --git a/aiohttp/test_utils.py b/aiohttp/test_utils.py index 315bb4526c5..5b664e0e10f 100644 --- a/aiohttp/test_utils.py +++ b/aiohttp/test_utils.py @@ -455,12 +455,12 @@ def get_app(self) -> Application: raise RuntimeError("Did you forget to define get_application()?") def setUp(self) -> None: - try: - self.loop = asyncio.get_running_loop() - except (AttributeError, RuntimeError): # AttributeError->py36 - self.loop = asyncio.get_event_loop_policy().get_event_loop() + if not PY_38: + asyncio.get_event_loop().run_until_complete(self.asyncSetUp()) - self.loop.run_until_complete(self.setUpAsync()) + async def asyncSetUp(self) -> None: + self.loop = asyncio.get_running_loop() + return await self.setUpAsync() async def setUpAsync(self) -> None: self.app = await self.get_application() @@ -470,7 +470,11 @@ async def setUpAsync(self) -> None: await self.client.start_server() def tearDown(self) -> None: - self.loop.run_until_complete(self.tearDownAsync()) + if not PY_38: + self.loop.run_until_complete(self.asyncTearDown()) + + async def asyncTearDown(self) -> None: + return await self.tearDownAsync() async def tearDownAsync(self) -> None: await self.client.close()