diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index a8044012c..8935c6105 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -174,7 +174,9 @@ async def _attempt_to_acquire_connection(self, status: RequestStatus) -> bool: # Attempt to close CONNECTING connections that no one needs if self._is_pool_full: - for idx, connection in enumerate(self._pool): # Try to check old connections first + for idx, connection in enumerate( + self._pool + ): # Try to check old connections first if not connection.is_connecting(): continue for req_status in self._requests: diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index a5c16c38e..9db49e632 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -174,7 +174,9 @@ def _attempt_to_acquire_connection(self, status: RequestStatus) -> bool: # Attempt to close CONNECTING connections that no one needs if self._is_pool_full: - for idx, connection in enumerate(self._pool): # Try to check old connections first + for idx, connection in enumerate( + self._pool + ): # Try to check old connections first if not connection.is_connecting(): continue for req_status in self._requests: diff --git a/httpcore/backends/mock.py b/httpcore/backends/mock.py index 871a2521d..0f18906f4 100644 --- a/httpcore/backends/mock.py +++ b/httpcore/backends/mock.py @@ -6,8 +6,9 @@ import anyio from httpcore import ReadTimeout -from .base import AsyncNetworkBackend, AsyncNetworkStream, NetworkBackend, NetworkStream + from .._exceptions import ReadError +from .base import AsyncNetworkBackend, AsyncNetworkStream, NetworkBackend, NetworkStream class MockSSLObject: @@ -59,10 +60,10 @@ def read(self, max_bytes: int, timeout: Optional[float] = None) -> bytes: class MockBackend(NetworkBackend): def __init__( - self, - buffer: typing.List[bytes], - http2: bool = False, - resp_stream_cls: Optional[Type[NetworkStream]] = None, + self, + buffer: typing.List[bytes], + http2: bool = False, + resp_stream_cls: Optional[Type[MockStream]] = None, ) -> None: self._buffer = buffer self._http2 = http2 @@ -127,14 +128,16 @@ async def read(self, max_bytes: int, timeout: Optional[float] = None) -> bytes: class AsyncMockBackend(AsyncNetworkBackend): def __init__( - self, - buffer: typing.List[bytes], - http2: bool = False, - resp_stream_cls: Optional[Type[AsyncNetworkStream]] = None, + self, + buffer: typing.List[bytes], + http2: bool = False, + resp_stream_cls: Optional[Type[AsyncMockStream]] = None, ) -> None: self._buffer = buffer self._http2 = http2 - self._resp_stream_cls: Type[AsyncMockStream] = resp_stream_cls or AsyncMockStream + self._resp_stream_cls: Type[AsyncMockStream] = ( + resp_stream_cls or AsyncMockStream + ) async def connect_tcp( self, diff --git a/tests/_async/test_connection_pool.py b/tests/_async/test_connection_pool.py index 6c45b020a..4e1c3c1bd 100644 --- a/tests/_async/test_connection_pool.py +++ b/tests/_async/test_connection_pool.py @@ -8,12 +8,12 @@ AsyncConnectionPool, ConnectError, PoolTimeout, - ReadTimeout, ReadError, + ReadTimeout, UnsupportedProtocol, ) from httpcore.backends.base import AsyncNetworkStream -from httpcore.backends.mock import AsyncMockBackend, AsyncHangingStream +from httpcore.backends.mock import AsyncHangingStream, AsyncMockBackend @pytest.mark.anyio @@ -511,19 +511,21 @@ async def test_pool_under_load(): """ network_backend = AsyncMockBackend([], resp_stream_cls=AsyncHangingStream) - async def fetch(_pool: AsyncConnectionPool, *exceptions: Type[BaseException]): + async def fetch( + _pool: AsyncConnectionPool, *exceptions: Type[BaseException] + ) -> None: with contextlib.suppress(*exceptions): async with pool.stream( - "GET", - "http://a.com/", - extensions={ - "timeout": { - "connect": 0.1, - "read": 0.1, - "pool": 0.1, - "write": 0.1, - }, + "GET", + "http://a.com/", + extensions={ + "timeout": { + "connect": 0.1, + "read": 0.1, + "pool": 0.1, + "write": 0.1, }, + }, ) as response: await response.aread() @@ -537,11 +539,12 @@ async def fetch(_pool: AsyncConnectionPool, *exceptions: Type[BaseException]): nursery.start_soon(fetch, pool, PoolTimeout, ReadTimeout) if pool.connections: # There is one connection in pool in "CONNECTING" state assert pool.connections[0].is_connecting() - with pytest.raises(ReadTimeout): # ReadTimeout indicates that connection could be retrieved + with pytest.raises( + ReadTimeout + ): # ReadTimeout indicates that connection could be retrieved await fetch(pool) - @pytest.mark.trio async def test_pool_timeout_connection_cleanup(): """ @@ -555,7 +558,8 @@ async def test_pool_timeout_connection_cleanup(): b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", - ] * 2, + ] + * 2, ) async with AsyncConnectionPool( @@ -568,12 +572,18 @@ async def test_pool_timeout_connection_cleanup(): "write": 0.1, } with contextlib.suppress(PoolTimeout): - await pool.request("GET", "https://example.com/", extensions={"timeout": timeout}) + await pool.request( + "GET", "https://example.com/", extensions={"timeout": timeout} + ) # wait for a considerable amount of time to make sure all requests time out await concurrency.sleep(0.1) - await pool.request("GET", "https://example.com/", extensions={"timeout": {**timeout, 'pool': 0.1}}) + await pool.request( + "GET", + "https://example.com/", + extensions={"timeout": {**timeout, "pool": 0.1}}, + ) if pool.connections: for conn in pool.connections: diff --git a/tests/_sync/test_connection_pool.py b/tests/_sync/test_connection_pool.py index 1384bef06..61744ed40 100644 --- a/tests/_sync/test_connection_pool.py +++ b/tests/_sync/test_connection_pool.py @@ -1,19 +1,18 @@ import contextlib -import time from typing import List, Optional, Type import pytest from httpcore import ( - ConnectionPool, ConnectError, + ConnectionPool, PoolTimeout, - ReadTimeout, ReadError, + ReadTimeout, UnsupportedProtocol, ) from httpcore.backends.base import NetworkStream -from httpcore.backends.mock import MockBackend, HangingStream +from httpcore.backends.mock import HangingStream, MockBackend from tests import concurrency @@ -511,7 +510,7 @@ def test_pool_under_load(): """ network_backend = MockBackend([], resp_stream_cls=HangingStream) - def fetch(_pool: ConnectionPool, *exceptions: Type[BaseException]): + def fetch(_pool: ConnectionPool, *exceptions: Type[BaseException]) -> None: with contextlib.suppress(*exceptions): with pool.stream( "GET", @@ -570,7 +569,7 @@ def test_pool_timeout_connection_cleanup(): pool.request("GET", "https://example.com/", extensions={"timeout": timeout}) # wait for a considerable amount of time to make sure all requests time out - time.sleep(0.1) + concurrency.sleep(0.1) pool.request("GET", "https://example.com/", extensions={"timeout": {**timeout, 'pool': 0.1}}) diff --git a/tests/concurrency.py b/tests/concurrency.py index 4582d538e..34a1dd60a 100644 --- a/tests/concurrency.py +++ b/tests/concurrency.py @@ -9,6 +9,7 @@ childen, because we don't need that for our use-case. """ import threading +import time from types import TracebackType from typing import Any, Callable, List, Optional, Type @@ -38,3 +39,7 @@ def start_soon(self, func: Callable[..., object], *args: Any) -> None: def open_nursery() -> Nursery: return Nursery() + + +def sleep(seconds: float) -> None: + time.sleep(seconds)