From 1edadb5d24a707a0dafbec43513a14dc2b1743b7 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Tue, 19 Sep 2023 19:27:22 +0330 Subject: [PATCH 01/17] Handle async cancelled error explicilty instead of `BaseException` --- httpcore/_async/connection_pool.py | 9 ++++++--- httpcore/_async/http11.py | 10 +++++++--- httpcore/_async/http2.py | 12 ++++++++---- httpcore/_synchronization.py | 20 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index ddc0510e..26c86f87 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -7,7 +7,9 @@ from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Request, Response -from .._synchronization import AsyncEvent, AsyncLock, AsyncShieldCancellation +from .._synchronization import ( + AsyncEvent, AsyncLock, AsyncShieldCancellation, get_cancelled_exc_class +) from .connection import AsyncHTTPConnection from .interfaces import AsyncConnectionInterface, AsyncRequestInterface @@ -113,6 +115,7 @@ def __init__( AutoBackend() if network_backend is None else network_backend ) self._socket_options = socket_options + self._cancelled_exc = get_cancelled_exc_class() def create_connection(self, origin: Origin) -> AsyncConnectionInterface: return AsyncHTTPConnection( @@ -231,7 +234,7 @@ async def handle_async_request(self, request: Request) -> Response: timeout = timeouts.get("pool", None) try: connection = await status.wait_for_connection(timeout=timeout) - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: # If we timeout here, or if the task is cancelled, then make # sure to remove the request from the queue before bubbling # up the exception. @@ -256,7 +259,7 @@ async def handle_async_request(self, request: Request) -> Response: # status so that the request becomes queued again. status.unset_connection() await self._attempt_to_acquire_connection(status) - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: with AsyncShieldCancellation(): await self.response_closed(status) raise exc diff --git a/httpcore/_async/http11.py b/httpcore/_async/http11.py index 32fa3a6f..919a548b 100644 --- a/httpcore/_async/http11.py +++ b/httpcore/_async/http11.py @@ -24,7 +24,9 @@ map_exceptions, ) from .._models import Origin, Request, Response -from .._synchronization import AsyncLock, AsyncShieldCancellation +from .._synchronization import ( + AsyncLock, AsyncShieldCancellation, get_cancelled_exc_class +) from .._trace import Trace from .interfaces import AsyncConnectionInterface @@ -67,6 +69,7 @@ def __init__( our_role=h11.CLIENT, max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, ) + self._cancelled_exc = get_cancelled_exc_class() async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): @@ -126,7 +129,7 @@ async def handle_async_request(self, request: Request) -> Response: "network_stream": self._network_stream, }, ) - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: with AsyncShieldCancellation(): async with Trace("response_closed", logger, request) as trace: await self._response_closed() @@ -321,6 +324,7 @@ def __init__(self, connection: AsyncHTTP11Connection, request: Request) -> None: self._connection = connection self._request = request self._closed = False + self._cancelled_exc = get_cancelled_exc_class() async def __aiter__(self) -> AsyncIterator[bytes]: kwargs = {"request": self._request} @@ -328,7 +332,7 @@ async def __aiter__(self) -> AsyncIterator[bytes]: async with Trace("receive_response_body", logger, self._request, kwargs): async for chunk in self._connection._receive_response_body(**kwargs): yield chunk - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index 8dc776ff..c9a36350 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -17,7 +17,9 @@ RemoteProtocolError, ) from .._models import Origin, Request, Response -from .._synchronization import AsyncLock, AsyncSemaphore, AsyncShieldCancellation +from .._synchronization import ( + AsyncLock, AsyncSemaphore, AsyncShieldCancellation, get_cancelled_exc_class +) from .._trace import Trace from .interfaces import AsyncConnectionInterface @@ -81,6 +83,7 @@ def __init__( self._read_exception: typing.Optional[Exception] = None self._write_exception: typing.Optional[Exception] = None + self._cancelled_exc = get_cancelled_exc_class() async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): @@ -107,7 +110,7 @@ async def handle_async_request(self, request: Request) -> Response: kwargs = {"request": request} async with Trace("send_connection_init", logger, request, kwargs): await self._send_connection_init(**kwargs) - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: with AsyncShieldCancellation(): await self.aclose() raise exc @@ -160,7 +163,7 @@ async def handle_async_request(self, request: Request) -> Response: "stream_id": stream_id, }, ) - except BaseException as exc: # noqa: PIE786 + except (Exception, self._cancelled_exc) as exc: # noqa: PIE786 with AsyncShieldCancellation(): kwargs = {"stream_id": stream_id} async with Trace("response_closed", logger, request, kwargs): @@ -564,6 +567,7 @@ def __init__( self._request = request self._stream_id = stream_id self._closed = False + self._cancelled_exc = get_cancelled_exc_class() async def __aiter__(self) -> typing.AsyncIterator[bytes]: kwargs = {"request": self._request, "stream_id": self._stream_id} @@ -573,7 +577,7 @@ async def __aiter__(self) -> typing.AsyncIterator[bytes]: request=self._request, stream_id=self._stream_id ): yield chunk - except BaseException as exc: + except (Exception, self._cancelled_exc) as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index bae27c1b..0ef7dec9 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -220,6 +220,26 @@ def __exit__( self._anyio_shield.__exit__(exc_type, exc_value, traceback) +def get_cancelled_exc_class(): + """ + Detect if we're running under 'asyncio' or 'trio' and create + a lock with the correct implementation. + """ + backend = sniffio.current_async_library() + if backend == "trio": + if trio is None: # pragma: nocover + raise RuntimeError( + "Running under trio, requires the 'trio' package to be installed." + ) + return trio.Cancelled + + if anyio is None: # pragma: nocover + raise RuntimeError( + "Running under asyncio requires the 'anyio' package to be installed." + ) + return anyio.get_cancelled_exc_class() + + # Our thread-based synchronization primitives... From 08ec5807f6de08c839966bb1dbc20ee849bfbbc6 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:14:49 +0330 Subject: [PATCH 02/17] isort --- httpcore/_async/connection_pool.py | 5 ++++- httpcore/_async/http11.py | 4 +++- httpcore/_async/http2.py | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 26c86f87..2fe9646b 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -8,7 +8,10 @@ from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Request, Response from .._synchronization import ( - AsyncEvent, AsyncLock, AsyncShieldCancellation, get_cancelled_exc_class + AsyncEvent, + AsyncLock, + AsyncShieldCancellation, + get_cancelled_exc_class, ) from .connection import AsyncHTTPConnection from .interfaces import AsyncConnectionInterface, AsyncRequestInterface diff --git a/httpcore/_async/http11.py b/httpcore/_async/http11.py index 919a548b..6b43e7bf 100644 --- a/httpcore/_async/http11.py +++ b/httpcore/_async/http11.py @@ -25,7 +25,9 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( - AsyncLock, AsyncShieldCancellation, get_cancelled_exc_class + AsyncLock, + AsyncShieldCancellation, + get_cancelled_exc_class, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index c9a36350..83f9d815 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -18,7 +18,10 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( - AsyncLock, AsyncSemaphore, AsyncShieldCancellation, get_cancelled_exc_class + AsyncLock, + AsyncSemaphore, + AsyncShieldCancellation, + get_cancelled_exc_class, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface From ed427e57fcc89dbb75cd127caa8de8385f20205c Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:22:21 +0330 Subject: [PATCH 03/17] typecheck --- httpcore/_synchronization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 0ef7dec9..9f1c0b51 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -220,10 +220,10 @@ def __exit__( self._anyio_shield.__exit__(exc_type, exc_value, traceback) -def get_cancelled_exc_class(): +def get_cancelled_exc_class() -> BaseException: """ - Detect if we're running under 'asyncio' or 'trio' and create - a lock with the correct implementation. + Detect if we're running under 'asyncio' or 'trio' and return + cannelled exception class of it. """ backend = sniffio.current_async_library() if backend == "trio": From 669095474a8fea2053952dd532f3321e0dccdd9d Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:24:51 +0330 Subject: [PATCH 04/17] lint --- httpcore/_synchronization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 9f1c0b51..30ae1566 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -223,7 +223,7 @@ def __exit__( def get_cancelled_exc_class() -> BaseException: """ Detect if we're running under 'asyncio' or 'trio' and return - cannelled exception class of it. + cannelled exception class of it. """ backend = sniffio.current_async_library() if backend == "trio": From a812d72ebded68efd546003ac8af063432561c56 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 00:19:11 +0330 Subject: [PATCH 05/17] typecheck --- httpcore/_synchronization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 30ae1566..078084b0 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -220,7 +220,7 @@ def __exit__( self._anyio_shield.__exit__(exc_type, exc_value, traceback) -def get_cancelled_exc_class() -> BaseException: +def get_cancelled_exc_class() -> Type[BaseException]: """ Detect if we're running under 'asyncio' or 'trio' and return cannelled exception class of it. From 488f15c2461923920d16540510fe3d7a051eae7a Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:17:25 +0330 Subject: [PATCH 06/17] `EXCEPTION_OR_CANCELLED` --- httpcore/_async/connection_pool.py | 7 +++---- httpcore/_async/http11.py | 8 +++----- httpcore/_async/http2.py | 10 ++++------ httpcore/_synchronization.py | 29 +++++++++-------------------- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 2fe9646b..4ed725d2 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -11,7 +11,7 @@ AsyncEvent, AsyncLock, AsyncShieldCancellation, - get_cancelled_exc_class, + EXCEPTION_OR_CANCELLED, ) from .connection import AsyncHTTPConnection from .interfaces import AsyncConnectionInterface, AsyncRequestInterface @@ -118,7 +118,6 @@ def __init__( AutoBackend() if network_backend is None else network_backend ) self._socket_options = socket_options - self._cancelled_exc = get_cancelled_exc_class() def create_connection(self, origin: Origin) -> AsyncConnectionInterface: return AsyncHTTPConnection( @@ -237,7 +236,7 @@ async def handle_async_request(self, request: Request) -> Response: timeout = timeouts.get("pool", None) try: connection = await status.wait_for_connection(timeout=timeout) - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we timeout here, or if the task is cancelled, then make # sure to remove the request from the queue before bubbling # up the exception. @@ -262,7 +261,7 @@ async def handle_async_request(self, request: Request) -> Response: # status so that the request becomes queued again. status.unset_connection() await self._attempt_to_acquire_connection(status) - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: with AsyncShieldCancellation(): await self.response_closed(status) raise exc diff --git a/httpcore/_async/http11.py b/httpcore/_async/http11.py index 6b43e7bf..a1433f68 100644 --- a/httpcore/_async/http11.py +++ b/httpcore/_async/http11.py @@ -27,7 +27,7 @@ from .._synchronization import ( AsyncLock, AsyncShieldCancellation, - get_cancelled_exc_class, + EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface @@ -71,7 +71,6 @@ def __init__( our_role=h11.CLIENT, max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, ) - self._cancelled_exc = get_cancelled_exc_class() async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): @@ -131,7 +130,7 @@ async def handle_async_request(self, request: Request) -> Response: "network_stream": self._network_stream, }, ) - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: with AsyncShieldCancellation(): async with Trace("response_closed", logger, request) as trace: await self._response_closed() @@ -326,7 +325,6 @@ def __init__(self, connection: AsyncHTTP11Connection, request: Request) -> None: self._connection = connection self._request = request self._closed = False - self._cancelled_exc = get_cancelled_exc_class() async def __aiter__(self) -> AsyncIterator[bytes]: kwargs = {"request": self._request} @@ -334,7 +332,7 @@ async def __aiter__(self) -> AsyncIterator[bytes]: async with Trace("receive_response_body", logger, self._request, kwargs): async for chunk in self._connection._receive_response_body(**kwargs): yield chunk - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index 83f9d815..e0a87569 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -21,7 +21,7 @@ AsyncLock, AsyncSemaphore, AsyncShieldCancellation, - get_cancelled_exc_class, + EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface @@ -86,7 +86,6 @@ def __init__( self._read_exception: typing.Optional[Exception] = None self._write_exception: typing.Optional[Exception] = None - self._cancelled_exc = get_cancelled_exc_class() async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): @@ -113,7 +112,7 @@ async def handle_async_request(self, request: Request) -> Response: kwargs = {"request": request} async with Trace("send_connection_init", logger, request, kwargs): await self._send_connection_init(**kwargs) - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: with AsyncShieldCancellation(): await self.aclose() raise exc @@ -166,7 +165,7 @@ async def handle_async_request(self, request: Request) -> Response: "stream_id": stream_id, }, ) - except (Exception, self._cancelled_exc) as exc: # noqa: PIE786 + except EXCEPTION_OR_CANCELLED as exc: # noqa: PIE786 with AsyncShieldCancellation(): kwargs = {"stream_id": stream_id} async with Trace("response_closed", logger, request, kwargs): @@ -570,7 +569,6 @@ def __init__( self._request = request self._stream_id = stream_id self._closed = False - self._cancelled_exc = get_cancelled_exc_class() async def __aiter__(self) -> typing.AsyncIterator[bytes]: kwargs = {"request": self._request, "stream_id": self._stream_id} @@ -580,7 +578,7 @@ async def __aiter__(self) -> typing.AsyncIterator[bytes]: request=self._request, stream_id=self._stream_id ): yield chunk - except (Exception, self._cancelled_exc) as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 078084b0..05b47268 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -6,16 +6,25 @@ from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions + +EXCEPTION_OR_CANCELLED = (Exception,) + # Our async synchronization primatives use either 'anyio' or 'trio' depending # on if they're running under asyncio or trio. try: import trio + EXCEPTION_OR_CANCELLED += (trio.Cancelled,) except ImportError: # pragma: nocover trio = None # type: ignore try: import anyio + try: + import asyncio + EXCEPTION_OR_CANCELLED += (asyncio.CancelledError,) + except ImportError: + pass except ImportError: # pragma: nocover anyio = None # type: ignore @@ -220,26 +229,6 @@ def __exit__( self._anyio_shield.__exit__(exc_type, exc_value, traceback) -def get_cancelled_exc_class() -> Type[BaseException]: - """ - Detect if we're running under 'asyncio' or 'trio' and return - cannelled exception class of it. - """ - backend = sniffio.current_async_library() - if backend == "trio": - if trio is None: # pragma: nocover - raise RuntimeError( - "Running under trio, requires the 'trio' package to be installed." - ) - return trio.Cancelled - - if anyio is None: # pragma: nocover - raise RuntimeError( - "Running under asyncio requires the 'anyio' package to be installed." - ) - return anyio.get_cancelled_exc_class() - - # Our thread-based synchronization primitives... From 907e5332c960a399a544267a47f4a8e3118fb116 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:24:23 +0330 Subject: [PATCH 07/17] sync --- httpcore/_sync/connection_pool.py | 11 ++++++++--- httpcore/_sync/http11.py | 10 +++++++--- httpcore/_sync/http2.py | 13 +++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index dbcaff1f..2028481e 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -7,7 +7,12 @@ from .._backends.base import SOCKET_OPTION, NetworkBackend from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Request, Response -from .._synchronization import Event, Lock, ShieldCancellation +from .._synchronization import ( + Event, + Lock, + ShieldCancellation, + EXCEPTION_OR_CANCELLED, +) from .connection import HTTPConnection from .interfaces import ConnectionInterface, RequestInterface @@ -231,7 +236,7 @@ def handle_request(self, request: Request) -> Response: timeout = timeouts.get("pool", None) try: connection = status.wait_for_connection(timeout=timeout) - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we timeout here, or if the task is cancelled, then make # sure to remove the request from the queue before bubbling # up the exception. @@ -256,7 +261,7 @@ def handle_request(self, request: Request) -> Response: # status so that the request becomes queued again. status.unset_connection() self._attempt_to_acquire_connection(status) - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: with ShieldCancellation(): self.response_closed(status) raise exc diff --git a/httpcore/_sync/http11.py b/httpcore/_sync/http11.py index 0cc100e3..d9f79bca 100644 --- a/httpcore/_sync/http11.py +++ b/httpcore/_sync/http11.py @@ -24,7 +24,11 @@ map_exceptions, ) from .._models import Origin, Request, Response -from .._synchronization import Lock, ShieldCancellation +from .._synchronization import ( + Lock, + ShieldCancellation, + EXCEPTION_OR_CANCELLED, +) from .._trace import Trace from .interfaces import ConnectionInterface @@ -126,7 +130,7 @@ def handle_request(self, request: Request) -> Response: "network_stream": self._network_stream, }, ) - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: with ShieldCancellation(): with Trace("response_closed", logger, request) as trace: self._response_closed() @@ -328,7 +332,7 @@ def __iter__(self) -> Iterator[bytes]: with Trace("receive_response_body", logger, self._request, kwargs): for chunk in self._connection._receive_response_body(**kwargs): yield chunk - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. diff --git a/httpcore/_sync/http2.py b/httpcore/_sync/http2.py index d141d459..74b74cea 100644 --- a/httpcore/_sync/http2.py +++ b/httpcore/_sync/http2.py @@ -17,7 +17,12 @@ RemoteProtocolError, ) from .._models import Origin, Request, Response -from .._synchronization import Lock, Semaphore, ShieldCancellation +from .._synchronization import ( + Lock, + Semaphore, + ShieldCancellation, + EXCEPTION_OR_CANCELLED, +) from .._trace import Trace from .interfaces import ConnectionInterface @@ -107,7 +112,7 @@ def handle_request(self, request: Request) -> Response: kwargs = {"request": request} with Trace("send_connection_init", logger, request, kwargs): self._send_connection_init(**kwargs) - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: with ShieldCancellation(): self.close() raise exc @@ -160,7 +165,7 @@ def handle_request(self, request: Request) -> Response: "stream_id": stream_id, }, ) - except BaseException as exc: # noqa: PIE786 + except EXCEPTION_OR_CANCELLED as exc: # noqa: PIE786 with ShieldCancellation(): kwargs = {"stream_id": stream_id} with Trace("response_closed", logger, request, kwargs): @@ -573,7 +578,7 @@ def __iter__(self) -> typing.Iterator[bytes]: request=self._request, stream_id=self._stream_id ): yield chunk - except BaseException as exc: + except EXCEPTION_OR_CANCELLED as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. From d110d8857a1db01d50e6f42717e1a987252c0c4c Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:28:31 +0330 Subject: [PATCH 08/17] isort --- httpcore/_async/connection_pool.py | 2 +- httpcore/_async/http11.py | 2 +- httpcore/_async/http2.py | 2 +- httpcore/_sync/connection_pool.py | 2 +- httpcore/_sync/http11.py | 2 +- httpcore/_sync/http2.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 4ed725d2..5aafa832 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -8,10 +8,10 @@ from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, AsyncEvent, AsyncLock, AsyncShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .connection import AsyncHTTPConnection from .interfaces import AsyncConnectionInterface, AsyncRequestInterface diff --git a/httpcore/_async/http11.py b/httpcore/_async/http11.py index a1433f68..99708e5d 100644 --- a/httpcore/_async/http11.py +++ b/httpcore/_async/http11.py @@ -25,9 +25,9 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, AsyncLock, AsyncShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index e0a87569..5b44f412 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -18,10 +18,10 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, AsyncLock, AsyncSemaphore, AsyncShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import AsyncConnectionInterface diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index 2028481e..c62b45f8 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -8,10 +8,10 @@ from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, Event, Lock, ShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .connection import HTTPConnection from .interfaces import ConnectionInterface, RequestInterface diff --git a/httpcore/_sync/http11.py b/httpcore/_sync/http11.py index d9f79bca..2307dc8d 100644 --- a/httpcore/_sync/http11.py +++ b/httpcore/_sync/http11.py @@ -25,9 +25,9 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, Lock, ShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import ConnectionInterface diff --git a/httpcore/_sync/http2.py b/httpcore/_sync/http2.py index 74b74cea..90966286 100644 --- a/httpcore/_sync/http2.py +++ b/httpcore/_sync/http2.py @@ -18,10 +18,10 @@ ) from .._models import Origin, Request, Response from .._synchronization import ( + EXCEPTION_OR_CANCELLED, Lock, Semaphore, ShieldCancellation, - EXCEPTION_OR_CANCELLED, ) from .._trace import Trace from .interfaces import ConnectionInterface From b32aea144ac9ffd13f1eeb95add4e8d06c60dbb5 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:32:54 +0330 Subject: [PATCH 09/17] Update httpcore/_synchronization.py --- httpcore/_synchronization.py | 1 - 1 file changed, 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 05b47268..2820f9b7 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -6,7 +6,6 @@ from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions - EXCEPTION_OR_CANCELLED = (Exception,) # Our async synchronization primatives use either 'anyio' or 'trio' depending From 9d5f236a6b6dda7e01161075527f26bd2e7ce581 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:49:28 +0330 Subject: [PATCH 10/17] fmt --- httpcore/_synchronization.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 2820f9b7..114a30ee 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -13,14 +13,17 @@ try: import trio + EXCEPTION_OR_CANCELLED += (trio.Cancelled,) except ImportError: # pragma: nocover trio = None # type: ignore try: import anyio + try: import asyncio + EXCEPTION_OR_CANCELLED += (asyncio.CancelledError,) except ImportError: pass From baa889f90a1435788968f587a6836c8195235486 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:56:33 +0330 Subject: [PATCH 11/17] typecheck --- httpcore/_synchronization.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 114a30ee..72b8c832 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -1,12 +1,12 @@ import threading from types import TracebackType -from typing import Optional, Type +from typing import Optional, Type, Tuple import sniffio from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions -EXCEPTION_OR_CANCELLED = (Exception,) +EXCEPTION_OR_CANCELLED: Tuple[Type[BaseException]] = (Exception,) # Our async synchronization primatives use either 'anyio' or 'trio' depending # on if they're running under asyncio or trio. From 76e4f4aef973289a2e75808fb8babeea3c24817c Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:59:20 +0330 Subject: [PATCH 12/17] Update httpcore/_synchronization.py --- httpcore/_synchronization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 72b8c832..5df31e17 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -1,6 +1,6 @@ import threading from types import TracebackType -from typing import Optional, Type, Tuple +from typing import Optional, Tuple, Type import sniffio From 9d6d4159875fe73325f9c1ee63d3c52fed0dea8a Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:14:31 +0330 Subject: [PATCH 13/17] Union Tuple Types --- httpcore/_synchronization.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 5df31e17..953427a7 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -1,12 +1,17 @@ import threading from types import TracebackType -from typing import Optional, Tuple, Type +from typing import Optional, Tuple, Type, Union import sniffio from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions -EXCEPTION_OR_CANCELLED: Tuple[Type[BaseException]] = (Exception,) + +EXCEPTION_OR_CANCELLED: Union[ + Tuple[Type[BaseException]], + Tuple[Type[BaseException], Type[BaseException]], + Tuple[Type[BaseException], Type[BaseException], Type[BaseException]], +] = (Exception,) # Our async synchronization primatives use either 'anyio' or 'trio' depending # on if they're running under asyncio or trio. From 4669673c318cb72a7a52d08da25eaf88fc70fb99 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:17:08 +0330 Subject: [PATCH 14/17] Update httpcore/_synchronization.py --- httpcore/_synchronization.py | 1 - 1 file changed, 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 953427a7..bbcd2541 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -6,7 +6,6 @@ from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions - EXCEPTION_OR_CANCELLED: Union[ Tuple[Type[BaseException]], Tuple[Type[BaseException], Type[BaseException]], From 131dc6126a870d235e7c8c92fce7de5359633ce9 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:23:08 +0330 Subject: [PATCH 15/17] Update httpcore/_synchronization.py Co-authored-by: Kar Petrosyan <92274156+karosis88@users.noreply.github.com> --- httpcore/_synchronization.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index bbcd2541..4eaaf9d6 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -6,11 +6,7 @@ from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions -EXCEPTION_OR_CANCELLED: Union[ - Tuple[Type[BaseException]], - Tuple[Type[BaseException], Type[BaseException]], - Tuple[Type[BaseException], Type[BaseException], Type[BaseException]], -] = (Exception,) +EXCEPTION_OR_CANCELLED: Tuple[Type[BaseException], ...] = (Exception,) # Our async synchronization primatives use either 'anyio' or 'trio' depending # on if they're running under asyncio or trio. From ffe420238c7b59d4db0f34b0584490ea6900e1c4 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:24:59 +0330 Subject: [PATCH 16/17] Update httpcore/_synchronization.py --- httpcore/_synchronization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 4eaaf9d6..dc45aa4c 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -1,6 +1,6 @@ import threading from types import TracebackType -from typing import Optional, Tuple, Type, Union +from typing import Optional, Tuple, Type import sniffio From d52ef2a0feafe706aa5351463124a86ee85df239 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Wed, 20 Sep 2023 18:30:01 +0330 Subject: [PATCH 17/17] Update httpcore/_synchronization.py --- httpcore/_synchronization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index dc45aa4c..20ca5ce5 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -25,7 +25,7 @@ import asyncio EXCEPTION_OR_CANCELLED += (asyncio.CancelledError,) - except ImportError: + except ImportError: # pragma: nocover pass except ImportError: # pragma: nocover anyio = None # type: ignore