From 1bd7faa1008c3b959af14da382dd28d1d00a8695 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 5 Feb 2025 18:59:14 -0600 Subject: [PATCH 01/39] [3.11] Increment version to 3.11.13.dev0 (#10420) --- aiohttp/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 4bafa848287..6652a0b979d 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.11.12" +__version__ = "3.11.13.dev0" from typing import TYPE_CHECKING, Tuple From c4523f3bc1c8972d8436e02e20d749c0b5823b07 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:23:31 +0000 Subject: [PATCH 02/39] [PR #10426/fae142f5 backport][3.11] Add benchmark for streaming API iter_chunks (#10427) Co-authored-by: J. Nick Koston --- tests/test_benchmarks_client.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/test_benchmarks_client.py b/tests/test_benchmarks_client.py index 61439183334..ac3131e9750 100644 --- a/tests/test_benchmarks_client.py +++ b/tests/test_benchmarks_client.py @@ -124,7 +124,7 @@ def test_one_hundred_get_requests_with_512kib_chunked_payload( aiohttp_client: AiohttpClient, benchmark: BenchmarkFixture, ) -> None: - """Benchmark 100 GET requests with a payload of 512KiB.""" + """Benchmark 100 GET requests with a payload of 512KiB using read.""" message_count = 100 payload = b"a" * (2**19) @@ -148,6 +148,36 @@ def _run() -> None: loop.run_until_complete(run_client_benchmark()) +def test_one_hundred_get_requests_iter_chunks_on_512kib_chunked_payload( + loop: asyncio.AbstractEventLoop, + aiohttp_client: AiohttpClient, + benchmark: BenchmarkFixture, +) -> None: + """Benchmark 100 GET requests with a payload of 512KiB using iter_chunks.""" + message_count = 100 + payload = b"a" * (2**19) + + async def handler(request: web.Request) -> web.Response: + resp = web.Response(body=payload) + resp.enable_chunked_encoding() + return resp + + app = web.Application() + app.router.add_route("GET", "/", handler) + + async def run_client_benchmark() -> None: + client = await aiohttp_client(app) + for _ in range(message_count): + resp = await client.get("/") + async for _ in resp.content.iter_chunks(): + pass + await client.close() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_client_benchmark()) + + def test_get_request_with_251308_compressed_chunked_payload( loop: asyncio.AbstractEventLoop, aiohttp_client: AiohttpClient, From 655c2f30abfe32f3137925e1663fb0d8a76cf297 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:29:44 +0000 Subject: [PATCH 03/39] [PR #10426/fae142f5 backport][3.12] Add benchmark for streaming API iter_chunks (#10428) Co-authored-by: J. Nick Koston --- tests/test_benchmarks_client.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/test_benchmarks_client.py b/tests/test_benchmarks_client.py index 61439183334..ac3131e9750 100644 --- a/tests/test_benchmarks_client.py +++ b/tests/test_benchmarks_client.py @@ -124,7 +124,7 @@ def test_one_hundred_get_requests_with_512kib_chunked_payload( aiohttp_client: AiohttpClient, benchmark: BenchmarkFixture, ) -> None: - """Benchmark 100 GET requests with a payload of 512KiB.""" + """Benchmark 100 GET requests with a payload of 512KiB using read.""" message_count = 100 payload = b"a" * (2**19) @@ -148,6 +148,36 @@ def _run() -> None: loop.run_until_complete(run_client_benchmark()) +def test_one_hundred_get_requests_iter_chunks_on_512kib_chunked_payload( + loop: asyncio.AbstractEventLoop, + aiohttp_client: AiohttpClient, + benchmark: BenchmarkFixture, +) -> None: + """Benchmark 100 GET requests with a payload of 512KiB using iter_chunks.""" + message_count = 100 + payload = b"a" * (2**19) + + async def handler(request: web.Request) -> web.Response: + resp = web.Response(body=payload) + resp.enable_chunked_encoding() + return resp + + app = web.Application() + app.router.add_route("GET", "/", handler) + + async def run_client_benchmark() -> None: + client = await aiohttp_client(app) + for _ in range(message_count): + resp = await client.get("/") + async for _ in resp.content.iter_chunks(): + pass + await client.close() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_client_benchmark()) + + def test_get_request_with_251308_compressed_chunked_payload( loop: asyncio.AbstractEventLoop, aiohttp_client: AiohttpClient, From cae5b2ed18cba9d35d9ca3f03346680f256a50a4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:59:54 +0000 Subject: [PATCH 04/39] [PR #10423/51daf719 backport][3.12] Disable writelines for test_write_large_payload_deflate_compression_data_in_eof (#10430) Co-authored-by: J. Nick Koston fixes #10421 --- CHANGES/10423.packaging.rst | 1 + tests/test_http_writer.py | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 CHANGES/10423.packaging.rst diff --git a/CHANGES/10423.packaging.rst b/CHANGES/10423.packaging.rst new file mode 100644 index 00000000000..6cf58c5a10b --- /dev/null +++ b/CHANGES/10423.packaging.rst @@ -0,0 +1 @@ +Fixed test ``test_write_large_payload_deflate_compression_data_in_eof_writelines`` failing with Python 3.12.9+ or 3.13.2+ -- by :user:`bdraco`. diff --git a/tests/test_http_writer.py b/tests/test_http_writer.py index 677b5bc9678..c39fe3c7251 100644 --- a/tests/test_http_writer.py +++ b/tests/test_http_writer.py @@ -19,6 +19,12 @@ def enable_writelines() -> Generator[None, None, None]: yield +@pytest.fixture +def disable_writelines() -> Generator[None, None, None]: + with mock.patch("aiohttp.http_writer.SKIP_WRITELINES", True): + yield + + @pytest.fixture def force_writelines_small_payloads() -> Generator[None, None, None]: with mock.patch("aiohttp.http_writer.MIN_PAYLOAD_FOR_WRITELINES", 1): @@ -104,6 +110,7 @@ async def test_write_payload_length(protocol, transport, loop) -> None: assert b"da" == content.split(b"\r\n\r\n", 1)[-1] +@pytest.mark.usefixtures("disable_writelines") async def test_write_large_payload_deflate_compression_data_in_eof( protocol: BaseProtocol, transport: asyncio.Transport, From a3d8bd346dd562a32f00f386b28c24cf28d40da8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:04:23 +0000 Subject: [PATCH 05/39] [PR #10422/289259d1 backport][3.12] Add human readable error messages for WebSocket PING/PONG timeouts (#10432) Co-authored-by: J. Nick Koston --- CHANGES/10422.misc.rst | 3 +++ aiohttp/client_ws.py | 4 +++- aiohttp/web_ws.py | 6 +++++- tests/test_client_ws_functional.py | 1 + tests/test_web_websocket_functional.py | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10422.misc.rst diff --git a/CHANGES/10422.misc.rst b/CHANGES/10422.misc.rst new file mode 100644 index 00000000000..7ecb1c0e2e2 --- /dev/null +++ b/CHANGES/10422.misc.rst @@ -0,0 +1,3 @@ +Added human-readable error messages to the exceptions for WebSocket disconnects due to PONG not being received -- by :user:`bdraco`. + +Previously, the error messages were empty strings, which made it hard to determine what went wrong. diff --git a/aiohttp/client_ws.py b/aiohttp/client_ws.py index f4cfa1bffe8..daa57d1930b 100644 --- a/aiohttp/client_ws.py +++ b/aiohttp/client_ws.py @@ -163,7 +163,9 @@ def _ping_task_done(self, task: "asyncio.Task[None]") -> None: self._ping_task = None def _pong_not_received(self) -> None: - self._handle_ping_pong_exception(ServerTimeoutError()) + self._handle_ping_pong_exception( + ServerTimeoutError(f"No PONG received after {self._pong_heartbeat} seconds") + ) def _handle_ping_pong_exception(self, exc: BaseException) -> None: """Handle exceptions raised during ping/pong processing.""" diff --git a/aiohttp/web_ws.py b/aiohttp/web_ws.py index 0fb1549a3aa..a448bca101e 100644 --- a/aiohttp/web_ws.py +++ b/aiohttp/web_ws.py @@ -182,7 +182,11 @@ def _ping_task_done(self, task: "asyncio.Task[None]") -> None: def _pong_not_received(self) -> None: if self._req is not None and self._req.transport is not None: - self._handle_ping_pong_exception(asyncio.TimeoutError()) + self._handle_ping_pong_exception( + asyncio.TimeoutError( + f"No PONG received after {self._pong_heartbeat} seconds" + ) + ) def _handle_ping_pong_exception(self, exc: BaseException) -> None: """Handle exceptions raised during ping/pong processing.""" diff --git a/tests/test_client_ws_functional.py b/tests/test_client_ws_functional.py index 7ede7432adf..54cd5e92f80 100644 --- a/tests/test_client_ws_functional.py +++ b/tests/test_client_ws_functional.py @@ -902,6 +902,7 @@ async def handler(request): assert resp.close_code is WSCloseCode.ABNORMAL_CLOSURE assert msg.type is WSMsgType.ERROR assert isinstance(msg.data, ServerTimeoutError) + assert str(msg.data) == "No PONG received after 0.05 seconds" async def test_close_websocket_while_ping_inflight( diff --git a/tests/test_web_websocket_functional.py b/tests/test_web_websocket_functional.py index b7494d9265f..945096a2af3 100644 --- a/tests/test_web_websocket_functional.py +++ b/tests/test_web_websocket_functional.py @@ -797,6 +797,7 @@ async def handler(request: web.Request) -> NoReturn: assert ws.close_code == WSCloseCode.ABNORMAL_CLOSURE assert ws_server_close_code == WSCloseCode.ABNORMAL_CLOSURE assert isinstance(ws_server_exception, asyncio.TimeoutError) + assert str(ws_server_exception) == "No PONG received after 0.025 seconds" await ws.close() From 5942b0bc37a2175f05d77b0403fc1c098eddf4f6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 17:11:39 +0000 Subject: [PATCH 06/39] [PR #10422/289259d1 backport][3.11] Add human readable error messages for WebSocket PING/PONG timeouts (#10431) Co-authored-by: J. Nick Koston --- CHANGES/10422.misc.rst | 3 +++ aiohttp/client_ws.py | 4 +++- aiohttp/web_ws.py | 6 +++++- tests/test_client_ws_functional.py | 1 + tests/test_web_websocket_functional.py | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10422.misc.rst diff --git a/CHANGES/10422.misc.rst b/CHANGES/10422.misc.rst new file mode 100644 index 00000000000..7ecb1c0e2e2 --- /dev/null +++ b/CHANGES/10422.misc.rst @@ -0,0 +1,3 @@ +Added human-readable error messages to the exceptions for WebSocket disconnects due to PONG not being received -- by :user:`bdraco`. + +Previously, the error messages were empty strings, which made it hard to determine what went wrong. diff --git a/aiohttp/client_ws.py b/aiohttp/client_ws.py index f4cfa1bffe8..daa57d1930b 100644 --- a/aiohttp/client_ws.py +++ b/aiohttp/client_ws.py @@ -163,7 +163,9 @@ def _ping_task_done(self, task: "asyncio.Task[None]") -> None: self._ping_task = None def _pong_not_received(self) -> None: - self._handle_ping_pong_exception(ServerTimeoutError()) + self._handle_ping_pong_exception( + ServerTimeoutError(f"No PONG received after {self._pong_heartbeat} seconds") + ) def _handle_ping_pong_exception(self, exc: BaseException) -> None: """Handle exceptions raised during ping/pong processing.""" diff --git a/aiohttp/web_ws.py b/aiohttp/web_ws.py index 0fb1549a3aa..a448bca101e 100644 --- a/aiohttp/web_ws.py +++ b/aiohttp/web_ws.py @@ -182,7 +182,11 @@ def _ping_task_done(self, task: "asyncio.Task[None]") -> None: def _pong_not_received(self) -> None: if self._req is not None and self._req.transport is not None: - self._handle_ping_pong_exception(asyncio.TimeoutError()) + self._handle_ping_pong_exception( + asyncio.TimeoutError( + f"No PONG received after {self._pong_heartbeat} seconds" + ) + ) def _handle_ping_pong_exception(self, exc: BaseException) -> None: """Handle exceptions raised during ping/pong processing.""" diff --git a/tests/test_client_ws_functional.py b/tests/test_client_ws_functional.py index 7ede7432adf..54cd5e92f80 100644 --- a/tests/test_client_ws_functional.py +++ b/tests/test_client_ws_functional.py @@ -902,6 +902,7 @@ async def handler(request): assert resp.close_code is WSCloseCode.ABNORMAL_CLOSURE assert msg.type is WSMsgType.ERROR assert isinstance(msg.data, ServerTimeoutError) + assert str(msg.data) == "No PONG received after 0.05 seconds" async def test_close_websocket_while_ping_inflight( diff --git a/tests/test_web_websocket_functional.py b/tests/test_web_websocket_functional.py index b7494d9265f..945096a2af3 100644 --- a/tests/test_web_websocket_functional.py +++ b/tests/test_web_websocket_functional.py @@ -797,6 +797,7 @@ async def handler(request: web.Request) -> NoReturn: assert ws.close_code == WSCloseCode.ABNORMAL_CLOSURE assert ws_server_close_code == WSCloseCode.ABNORMAL_CLOSURE assert isinstance(ws_server_exception, asyncio.TimeoutError) + assert str(ws_server_exception) == "No PONG received after 0.025 seconds" await ws.close() From 0ed7f2fb66831c87463ff834da41385b5e20ad7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 20:53:15 +0000 Subject: [PATCH 07/39] Bump mypy from 1.11.2 to 1.15.0 (#10385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [mypy](https://github.com/python/mypy) from 1.11.2 to 1.15.0.
Changelog

Sourced from mypy's changelog.

Mypy Release Notes

Next Release

...

Mypy 1.15

We’ve just uploaded mypy 1.15 to the Python Package Index (PyPI). Mypy is a static type checker for Python. This release includes new features, performance improvements and bug fixes. You can install it as follows:

python3 -m pip install -U mypy

You can read the full documentation for this release on Read the Docs.

Performance Improvements

Mypy is up to 40% faster in some use cases. This improvement comes largely from tuning the performance of the garbage collector. Additionally, the release includes several micro-optimizations that may be impactful for large projects.

Contributed by Jukka Lehtosalo

Mypyc Accelerated Mypy Wheels for ARM Linux

For best performance, mypy can be compiled to C extension modules using mypyc. This makes mypy 3-5x faster than when interpreted with pure Python. We now build and upload mypyc accelerated mypy wheels for manylinux_aarch64 to PyPI, making it easy for Linux users on ARM platforms to realise this speedup -- just pip install the latest mypy.

Contributed by Christian Bundy and Marc Mueller (PR mypy_mypyc-wheels#76, PR mypy_mypyc-wheels#89).

--strict-bytes

By default, mypy treats bytearray and memoryview values as assignable to the bytes type, for historical reasons. Use the --strict-bytes flag to disable this behavior. PEP 688 specified the removal of this special case. The flag will be enabled by default in mypy 2.0.

Contributed by Ali Hamdan (PR 18263) and Shantanu Jain (PR 13952).

Improvements to Reachability Analysis and Partial Type Handling in Loops

... (truncated)

Commits
  • 9397454 remove +dev from version ahead of final release
  • 686b591 remove "unreleased" from 1.15 changelog entry
  • cb4b243 Various small updates to 1.15 changelog (#18599)
  • 1a26502 Prepare changelog for 1.15 release (#18583)
  • d4515e4 Fix a few PR links in the changelog (#18586)
  • f83b643 Add object self-type to tuple test fixture (#18592)
  • ebc2cb8 Prevent crash on generic NamedTuple with unresolved typevar bound (#18585)
  • 63c251e empty commit to trigger wheel rebuild
  • c30573e Fix literal context for ternary expressions (for real) (#18545)
  • 23d862d Fix isinstance with explicit (non generic) type alias (#18512)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mypy&package-manager=pip&previous-version=1.11.2&new-version=1.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sam Bull Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- aiohttp/web.py | 2 +- aiohttp/web_app.py | 4 ++-- aiohttp/web_fileresponse.py | 2 +- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- requirements/test.txt | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aiohttp/web.py b/aiohttp/web.py index d6ab6f6fad4..8307ff405ca 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -345,7 +345,7 @@ async def _run_app( try: if host is not None: - if isinstance(host, (str, bytes, bytearray, memoryview)): + if isinstance(host, str): sites.append( TCPSite( runner, diff --git a/aiohttp/web_app.py b/aiohttp/web_app.py index 4bdc54034de..854f9bce88d 100644 --- a/aiohttp/web_app.py +++ b/aiohttp/web_app.py @@ -86,7 +86,7 @@ def _build_middlewares( """Apply middlewares to handler.""" for app in apps[::-1]: for m, _ in app._middlewares_handlers: # type: ignore[union-attr] - handler = update_wrapper(partial(m, handler=handler), handler) # type: ignore[misc] + handler = update_wrapper(partial(m, handler=handler), handler) return handler @@ -561,7 +561,7 @@ async def _handle(self, request: Request) -> StreamResponse: for m, new_style in app._middlewares_handlers: # type: ignore[union-attr] if new_style: handler = update_wrapper( - partial(m, handler=handler), handler # type: ignore[misc] + partial(m, handler=handler), handler ) else: handler = await m(app, handler) # type: ignore[arg-type,assignment] diff --git a/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py index be9cf87e069..344611cc495 100644 --- a/aiohttp/web_fileresponse.py +++ b/aiohttp/web_fileresponse.py @@ -83,7 +83,7 @@ class _FileResponseResult(Enum): # Add custom pairs and clear the encodings map so guess_type ignores them. CONTENT_TYPES.encodings_map.clear() for content_type, extension in ADDITIONAL_CONTENT_TYPES.items(): - CONTENT_TYPES.add_type(content_type, extension) # type: ignore[attr-defined] + CONTENT_TYPES.add_type(content_type, extension) _CLOSE_FUTURES: Set[asyncio.Future[None]] = set() diff --git a/requirements/constraints.txt b/requirements/constraints.txt index f6f9adbf39d..630217808ea 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -110,7 +110,7 @@ multidict==6.1.0 # -r requirements/multidict.in # -r requirements/runtime-deps.in # yarl -mypy==1.11.2 ; implementation_name == "cpython" +mypy==1.15.0 ; implementation_name == "cpython" # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 5d87c1ebaba..a9526e88f37 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -107,7 +107,7 @@ multidict==6.1.0 # via # -r requirements/runtime-deps.in # yarl -mypy==1.11.2 ; implementation_name == "cpython" +mypy==1.15.0 ; implementation_name == "cpython" # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/lint.txt b/requirements/lint.txt index dd06ec7236f..7fff423e368 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -39,7 +39,7 @@ markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py -mypy==1.11.2 ; implementation_name == "cpython" +mypy==1.15.0 ; implementation_name == "cpython" # via -r requirements/lint.in mypy-extensions==1.0.0 # via mypy diff --git a/requirements/test.txt b/requirements/test.txt index efd44e1ea3f..f43cbdf0f40 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -57,7 +57,7 @@ multidict==6.1.0 # via # -r requirements/runtime-deps.in # yarl -mypy==1.11.2 ; implementation_name == "cpython" +mypy==1.15.0 ; implementation_name == "cpython" # via -r requirements/test.in mypy-extensions==1.0.0 # via mypy From cf19b0434bfd2c62d42478333211432b460b7e3a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 18:27:07 +0000 Subject: [PATCH 08/39] [PR #10423/51daf719 backport][3.11] Disable writelines for test_write_large_payload_deflate_compression_data_in_eof (#10429) Co-authored-by: J. Nick Koston fixes #10421 --- CHANGES/10423.packaging.rst | 1 + tests/test_http_writer.py | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 CHANGES/10423.packaging.rst diff --git a/CHANGES/10423.packaging.rst b/CHANGES/10423.packaging.rst new file mode 100644 index 00000000000..6cf58c5a10b --- /dev/null +++ b/CHANGES/10423.packaging.rst @@ -0,0 +1 @@ +Fixed test ``test_write_large_payload_deflate_compression_data_in_eof_writelines`` failing with Python 3.12.9+ or 3.13.2+ -- by :user:`bdraco`. diff --git a/tests/test_http_writer.py b/tests/test_http_writer.py index 677b5bc9678..c39fe3c7251 100644 --- a/tests/test_http_writer.py +++ b/tests/test_http_writer.py @@ -19,6 +19,12 @@ def enable_writelines() -> Generator[None, None, None]: yield +@pytest.fixture +def disable_writelines() -> Generator[None, None, None]: + with mock.patch("aiohttp.http_writer.SKIP_WRITELINES", True): + yield + + @pytest.fixture def force_writelines_small_payloads() -> Generator[None, None, None]: with mock.patch("aiohttp.http_writer.MIN_PAYLOAD_FOR_WRITELINES", 1): @@ -104,6 +110,7 @@ async def test_write_payload_length(protocol, transport, loop) -> None: assert b"da" == content.split(b"\r\n\r\n", 1)[-1] +@pytest.mark.usefixtures("disable_writelines") async def test_write_large_payload_deflate_compression_data_in_eof( protocol: BaseProtocol, transport: asyncio.Transport, From b020505891a8ef79f175e676841ed29090886b40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:50:58 +0000 Subject: [PATCH 09/39] Bump aiohappyeyeballs from 2.4.4 to 2.4.6 (#10441) Bumps [aiohappyeyeballs](https://github.com/aio-libs/aiohappyeyeballs) from 2.4.4 to 2.4.6.
Release notes

Sourced from aiohappyeyeballs's releases.

v2.4.6 (2025-02-07)

Bug Fixes

  • Ensure all timers are cancelled when after staggered race finishes (#136, f75891d)

Detailed Changes: v2.4.5...v2.4.6

v2.4.5 (2025-02-07)

Bug Fixes

  • Keep classifiers in project to avoid automatic enrichment (#134, 99edb20)

Co-authored-by: J. Nick Koston nick@koston.org

  • Move classifiers to prevent recalculation by Poetry (#131, 66e1c90)

Co-authored-by: Martin Styk martin.styk@oracle.com

Co-authored-by: J. Nick Koston nick@koston.org


Detailed Changes: v2.4.4...v2.4.5

Changelog

Sourced from aiohappyeyeballs's changelog.

v2.4.6 (2025-02-07)

Bug fixes

  • Ensure all timers are cancelled when after staggered race finishes (#136) (f75891d)

v2.4.5 (2025-02-07)

Bug fixes

  • Keep classifiers in project to avoid automatic enrichment (#134) (99edb20)
  • Move classifiers to prevent recalculation by poetry (#131) (66e1c90)
Commits
  • f18ad49 2.4.6
  • f75891d fix: ensure all timers are cancelled when after staggered race finishes (#136)
  • cbc674d 2.4.5
  • 99edb20 fix: keep classifiers in project to avoid automatic enrichment (#134)
  • 9baf0b3 chore(deps-ci): bump the github-actions group with 9 updates (#135)
  • 678eab0 chore: update dependabot.yml to include GHA (#133)
  • 66e1c90 fix: move classifiers to prevent recalculation by Poetry (#131)
  • 850640e chore: migrate to poetry 2.0 (#132)
  • 75ec0dc chore(pre-commit.ci): pre-commit autoupdate (#129)
  • 7d7f118 chore(pre-commit.ci): pre-commit autoupdate (#128)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohappyeyeballs&package-manager=pip&previous-version=2.4.4&new-version=2.4.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/base.txt | 2 +- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/runtime-deps.txt | 2 +- requirements/test.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index ddd4e082f20..45a1fac6fa4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -6,7 +6,7 @@ # aiodns==3.2.0 ; sys_platform == "linux" or sys_platform == "darwin" # via -r requirements/runtime-deps.in -aiohappyeyeballs==2.4.4 +aiohappyeyeballs==2.4.6 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 630217808ea..f980be60a22 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -8,7 +8,7 @@ aiodns==3.2.0 ; sys_platform == "linux" or sys_platform == "darwin" # via # -r requirements/lint.in # -r requirements/runtime-deps.in -aiohappyeyeballs==2.4.4 +aiohappyeyeballs==2.4.6 # via -r requirements/runtime-deps.in aiohttp-theme==0.1.7 # via -r requirements/doc.in diff --git a/requirements/dev.txt b/requirements/dev.txt index a9526e88f37..59f7ba4db2c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -8,7 +8,7 @@ aiodns==3.2.0 ; sys_platform == "linux" or sys_platform == "darwin" # via # -r requirements/lint.in # -r requirements/runtime-deps.in -aiohappyeyeballs==2.4.4 +aiohappyeyeballs==2.4.6 # via -r requirements/runtime-deps.in aiohttp-theme==0.1.7 # via -r requirements/doc.in diff --git a/requirements/runtime-deps.txt b/requirements/runtime-deps.txt index fcc9a417a1a..118f584b7dd 100644 --- a/requirements/runtime-deps.txt +++ b/requirements/runtime-deps.txt @@ -6,7 +6,7 @@ # aiodns==3.2.0 ; sys_platform == "linux" or sys_platform == "darwin" # via -r requirements/runtime-deps.in -aiohappyeyeballs==2.4.4 +aiohappyeyeballs==2.4.6 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in diff --git a/requirements/test.txt b/requirements/test.txt index f43cbdf0f40..f0a0b0843e5 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -6,7 +6,7 @@ # aiodns==3.2.0 ; sys_platform == "linux" or sys_platform == "darwin" # via -r requirements/runtime-deps.in -aiohappyeyeballs==2.4.4 +aiohappyeyeballs==2.4.6 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in From ba3228ee56a6d10d65e8d0870275470717998048 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:51:06 +0000 Subject: [PATCH 10/39] Bump pip from 25.0 to 25.0.1 (#10442) Bumps [pip](https://github.com/pypa/pip) from 25.0 to 25.0.1.
Changelog

Sourced from pip's changelog.

25.0.1 (2025-02-09)

Bug Fixes

  • Fix an unsupported type annotation on Python 3.10 and earlier. ([#13181](https://github.com/pypa/pip/issues/13181) <https://github.com/pypa/pip/issues/13181>_)
  • Fix a regression where truststore would never be used while installing build dependencies. ([#13186](https://github.com/pypa/pip/issues/13186) <https://github.com/pypa/pip/issues/13186>_)
Commits
  • bc7c88c Bump for release
  • ebd0a52 Don't pass --cert to build subprocesses unless also given on CLI
  • aea8629 Fix locate_file() type hints for older Pythons
  • e612988 Add build-project.py compatibility note
  • 202344e Update the release process docs
  • dc696c2 Patch out EXTERNALLY-MANAGED for self-check tests (#13179)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pip&package-manager=pip&previous-version=25.0&new-version=25.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index f980be60a22..ecbda3707d0 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -280,7 +280,7 @@ yarl==1.18.3 # via -r requirements/runtime-deps.in # The following packages are considered to be unsafe in a requirements file: -pip==25.0 +pip==25.0.1 # via pip-tools setuptools==75.8.0 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index 59f7ba4db2c..cecd1357f0c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -271,7 +271,7 @@ yarl==1.18.3 # via -r requirements/runtime-deps.in # The following packages are considered to be unsafe in a requirements file: -pip==25.0 +pip==25.0.1 # via pip-tools setuptools==75.8.0 # via From ccbe9ace5f2f6713ff625b7270c01a6bdb4a3811 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:58:16 +0000 Subject: [PATCH 11/39] Bump coverage from 7.6.10 to 7.6.11 (#10444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.10 to 7.6.11.
Changelog

Sourced from coverage's changelog.

Version 7.6.11 — 2025-02-08

  • Fix: a memory leak in CTracer has been fixed. The details are in issue 1924_ and pytest-dev 676_. This should reduce the memory footprint for everyone even if it hadn't caused a problem before.

  • We now ship a py3-none-any.whl wheel file. Thanks, Russell Keith-Magee <pull 1914_>_.

.. _pull 1914: nedbat/coveragepy#1914 .. _issue 1924: nedbat/coveragepy#1924 .. _pytest-dev 676: pytest-dev/pytest-cov#676

.. _changes_7-6-10:

Commits
  • a20898d docs: sample HTML for 7.6.11
  • 938d519 docs: prep for 7.6.11
  • 27ee4ff test: free-threading builds were failing the old leak test #1924
  • f473b87 test: it could be useful to disable branch coverage in this helper
  • f85d9b7 fix: prevent code objects from leaking #1924
  • ae8d3b9 chore: make upgrade
  • 156981f build: zizmor can't tell this is safe
  • 6603021 chore: bump the action-dependencies group with 6 updates (#1922)
  • d6a1e5b test: run the pytracer first so .tox is left with a c extension for ad-hoc use
  • cd2db93 docs: a reminder about when RESUME applies
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=coverage&package-manager=pip&previous-version=7.6.10&new-version=7.6.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/test.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index ecbda3707d0..5d6b50a66aa 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -50,7 +50,7 @@ click==8.1.8 # slotscheck # towncrier # wait-for-it -coverage==7.6.10 +coverage==7.6.11 # via # -r requirements/test.in # pytest-cov diff --git a/requirements/dev.txt b/requirements/dev.txt index cecd1357f0c..1b89ccc6356 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -50,7 +50,7 @@ click==8.1.8 # slotscheck # towncrier # wait-for-it -coverage==7.6.10 +coverage==7.6.11 # via # -r requirements/test.in # pytest-cov diff --git a/requirements/test.txt b/requirements/test.txt index f0a0b0843e5..8212c20a0f4 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -25,7 +25,7 @@ cffi==1.17.1 # pytest-codspeed click==8.1.8 # via wait-for-it -coverage==7.6.10 +coverage==7.6.11 # via # -r requirements/test.in # pytest-cov From 1ea755908423b131636739c8dae95a1e5935048b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:31:49 +0000 Subject: [PATCH 12/39] [PR #10447/343c632d backport][3.12] Fix test when symlink encountered (#10449) **This is a backport of PR #10447 as merged into master (343c632d2a6626c0c46aec588ab50c373550c5c4).** Co-authored-by: Sam Bull --- tests/test_urldispatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 8ee3df33202..ba6bdff23a0 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -358,7 +358,7 @@ def test_add_static_path_resolution(router: any) -> None: """Test that static paths are expanded and absolute.""" res = router.add_static("/", "~/..") directory = str(res.get_info()["directory"]) - assert directory == str(pathlib.Path.home().parent) + assert directory == str(pathlib.Path.home().resolve(strict=True).parent) def test_add_static(router) -> None: From 094bf4eea616b169e585a20c4d8962870fc74a02 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 01:20:46 +0000 Subject: [PATCH 13/39] [PR #10447/343c632d backport][3.11] Fix test when symlink encountered (#10448) **This is a backport of PR #10447 as merged into master (343c632d2a6626c0c46aec588ab50c373550c5c4).** Co-authored-by: Sam Bull --- tests/test_urldispatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 8ee3df33202..ba6bdff23a0 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -358,7 +358,7 @@ def test_add_static_path_resolution(router: any) -> None: """Test that static paths are expanded and absolute.""" res = router.add_static("/", "~/..") directory = str(res.get_info()["directory"]) - assert directory == str(pathlib.Path.home().parent) + assert directory == str(pathlib.Path.home().resolve(strict=True).parent) def test_add_static(router) -> None: From 75f7b1869d6e3495f9f9cb44c31dcfd274b6a438 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 11:15:48 +0000 Subject: [PATCH 14/39] Bump cython from 3.0.11 to 3.0.12 (#10452) Bumps [cython](https://github.com/cython/cython) from 3.0.11 to 3.0.12.
Changelog

Sourced from cython's changelog.

3.0.12 (2025-02-11)

Bugs fixed

  • Release 3.0.11 introduced some incorrect noexcept warnings. (Github issue :issue:6335)

  • Conditional assignments to variables using the walrus operator could crash. (Github issue :issue:6094)

  • Dict assignments to struct members with reserved C names could generate invalid C code.

  • Fused ctuples with the same entry types but different sizes could fail to compile. (Github issue :issue:6328)

  • In Py3, pyximport was not searching sys.path when looking for importable source files. (Github issue :issue:5615)

  • Using & 0 on integers produced with int.from_bytes() could read invalid memory on Python 3.10. (Github issue :issue:6480)

  • Modules could fail to compile in PyPy 3.11 due to missing CPython specific header files. Patch by Matti Picus. (Github issue :issue:6482)

  • Minor fix in C++ partial_sum() declaration.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cython&package-manager=pip&previous-version=3.0.11&new-version=3.0.12)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/cython.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 5d6b50a66aa..d9012a53c36 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -58,7 +58,7 @@ cryptography==44.0.0 # via # pyjwt # trustme -cython==3.0.11 +cython==3.0.12 # via -r requirements/cython.in distlib==0.3.9 # via virtualenv diff --git a/requirements/cython.txt b/requirements/cython.txt index 7e392bddf91..b34cde941f8 100644 --- a/requirements/cython.txt +++ b/requirements/cython.txt @@ -4,7 +4,7 @@ # # pip-compile --allow-unsafe --output-file=requirements/cython.txt --resolver=backtracking --strip-extras requirements/cython.in # -cython==3.0.11 +cython==3.0.12 # via -r requirements/cython.in multidict==6.1.0 # via -r requirements/multidict.in From 328275b3121490a202e1c5261298e6c32aef0d23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 11:31:08 +0000 Subject: [PATCH 15/39] Bump virtualenv from 20.29.1 to 20.29.2 (#10453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.29.1 to 20.29.2.
Release notes

Sourced from virtualenv's releases.

20.29.2

What's Changed

Full Changelog: https://github.com/pypa/virtualenv/compare/20.29.1...20.29.2

Changelog

Sourced from virtualenv's changelog.

v20.29.2 (2025-02-10)

Bugfixes - 20.29.2

- Remove old virtualenv wheel from the source distribution -
by :user:`gaborbernat`. (:issue:`2841`)
- Upgrade embedded wheel pip to ``25.0.1`` from ``24.3.1`` - by
:user:`gaborbernat`. (:issue:`2843`)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=virtualenv&package-manager=pip&previous-version=20.29.1&new-version=20.29.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index d9012a53c36..7adbab8939a 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -270,7 +270,7 @@ uvloop==0.21.0 ; platform_system != "Windows" # -r requirements/lint.in valkey==6.0.2 # via -r requirements/lint.in -virtualenv==20.29.1 +virtualenv==20.29.2 # via pre-commit wait-for-it==2.3.0 # via -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 1b89ccc6356..1b1fd3555e0 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -261,7 +261,7 @@ uvloop==0.21.0 ; platform_system != "Windows" and implementation_name == "cpytho # -r requirements/lint.in valkey==6.0.2 # via -r requirements/lint.in -virtualenv==20.29.1 +virtualenv==20.29.2 # via pre-commit wait-for-it==2.3.0 # via -r requirements/test.in diff --git a/requirements/lint.txt b/requirements/lint.txt index 7fff423e368..40713fc30b1 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -102,5 +102,5 @@ uvloop==0.21.0 ; platform_system != "Windows" # via -r requirements/lint.in valkey==6.0.2 # via -r requirements/lint.in -virtualenv==20.29.1 +virtualenv==20.29.2 # via pre-commit From c0871b018f7d9beec5bb4d49e88ea83f58098641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:14:39 +0000 Subject: [PATCH 16/39] Bump valkey from 6.0.2 to 6.1.0 (#10460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [valkey](https://github.com/valkey-io/valkey-py) from 6.0.2 to 6.1.0.
Release notes

Sourced from valkey's releases.

6.1.0

Changes

  • v6.1.0 (#173)
  • Fix updated linters errors (#172)
  • Removing my work account from CODEOWNERS (#168)
  • connection: fix getpid() call on disconnect (#166)
  • Revert some typing commits (#163)
  • fixed type hints of hash methods (#154)
  • fixed type hint of hrandfield method (#155)
  • Add new CODEOWNERS (#152)
  • Add more test cases (#147)
  • refactor: updating typing for xreadgroup / xread / xadd (#130)
  • update typing for copy (#139)
  • update the return type of scan family (#135)
  • Issue 131: Fixes Flaky test by increasing timeout to 1s (#136)
  • Fixes for valkey 8.0 (#124)
  • Set socket_timeout default value to 5 seconds (#120)
  • sort methods ACL DELUSER and ACL DRYRUN by alphabetically, checked doc (#103)
  • drop compose format and commands v1, use supported v2+ (#105)
  • fix redis-cluster-py link (#99)
  • make documentation link more obvious (#98)
  • Added geosearch tests (#97)

🔥 Breaking Changes

  • Remove expiration/TTL commands that are not supported by Valkey (#125)

🚀 New Features

  • Add dynamic_startup_nodes parameter to async ValkeyCluster (#167)
  • fixed problems in #143 (#144)
  • Add async class aliases for redis-py compatibility (#148)

🐛 Bug Fixes

  • Allow relative path in unix socket URLs (#153)

🧰 Maintenance

  • connection: add a pointer to os.getpid to ConnectionPool (#159)
  • fix verify params in getex() (#145)
  • build(deps): bump rojopolis/spellcheck-github-actions from 0.44.0 to 0.45.0 (#128)
  • build(deps): bump codecov/codecov-action from 4 to 5 (#127)
  • Add support for Python 3.13 (#116)
  • build(deps): bump rojopolis/spellcheck-github-actions from 0.42.0 to 0.44.0 (#118)
  • Revert "Temporarily fix https://github.com/actions/runner-images/issu…" (#117)
  • parsers: resp3: be less verbose (#112)
  • Temporarily fix actions/runner-images#10781 (#113)
  • build(deps): bump rojopolis/spellcheck-github-actions from 0.41.0 to 0.42.0 (#108)

... (truncated)

Commits
  • 95c4b68 Merge pull request #173 from valkey-io/mkmkme/6.1.0
  • a589997 v6.1.0
  • 2d648a4 Merge pull request #172 from valkey-io/mkmkme/fix-isort
  • 05e1f31 tests: fix floating-point error for georadius tests
  • 81f63b3 fix black formatting
  • 0b825f1 tests: fix flynt error
  • d0e5bdf url_parser: fix isort error
  • 457be2d Merge pull request #168 from valkey-io/aiven-sal/removeme
  • e4025bd Removing my work account from CODEOWNERS
  • bcd5e2c Merge pull request #167 from Kakadus/2472redis-add-dynamic-startup-nodes-flag...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=valkey&package-manager=pip&previous-version=6.0.2&new-version=6.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 7adbab8939a..0938b5496a6 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -268,7 +268,7 @@ uvloop==0.21.0 ; platform_system != "Windows" # via # -r requirements/base.in # -r requirements/lint.in -valkey==6.0.2 +valkey==6.1.0 # via -r requirements/lint.in virtualenv==20.29.2 # via pre-commit diff --git a/requirements/dev.txt b/requirements/dev.txt index 1b1fd3555e0..905505a08fa 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -259,7 +259,7 @@ uvloop==0.21.0 ; platform_system != "Windows" and implementation_name == "cpytho # via # -r requirements/base.in # -r requirements/lint.in -valkey==6.0.2 +valkey==6.1.0 # via -r requirements/lint.in virtualenv==20.29.2 # via pre-commit diff --git a/requirements/lint.txt b/requirements/lint.txt index 40713fc30b1..81ab07708bf 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -100,7 +100,7 @@ typing-extensions==4.12.2 # rich uvloop==0.21.0 ; platform_system != "Windows" # via -r requirements/lint.in -valkey==6.0.2 +valkey==6.1.0 # via -r requirements/lint.in virtualenv==20.29.2 # via pre-commit From b8b7159e0ff6052528fe5a1cec05c2f3c5047798 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:16:09 +0000 Subject: [PATCH 17/39] Bump cryptography from 44.0.0 to 44.0.1 (#10461) Bumps [cryptography](https://github.com/pyca/cryptography) from 44.0.0 to 44.0.1.
Changelog

Sourced from cryptography's changelog.

44.0.1 - 2025-02-11


* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL
3.4.1.
* We now build ``armv7l`` ``manylinux`` wheels and publish them to PyPI.
* We now build ``manylinux_2_34`` wheels and publish them to PyPI.

.. _v44-0-0:

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cryptography&package-manager=pip&previous-version=44.0.0&new-version=44.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- requirements/test.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 0938b5496a6..9cd66c31096 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -54,7 +54,7 @@ coverage==7.6.11 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.0 +cryptography==44.0.1 # via # pyjwt # trustme diff --git a/requirements/dev.txt b/requirements/dev.txt index 905505a08fa..e97b52d4c97 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -54,7 +54,7 @@ coverage==7.6.11 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.0 +cryptography==44.0.1 # via # pyjwt # trustme diff --git a/requirements/lint.txt b/requirements/lint.txt index 81ab07708bf..57fdc34c119 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -19,7 +19,7 @@ cfgv==3.4.0 # via pre-commit click==8.1.8 # via slotscheck -cryptography==44.0.0 +cryptography==44.0.1 # via trustme distlib==0.3.9 # via virtualenv diff --git a/requirements/test.txt b/requirements/test.txt index 8212c20a0f4..791bc28e9b4 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -29,7 +29,7 @@ coverage==7.6.11 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.0 +cryptography==44.0.1 # via trustme exceptiongroup==1.2.2 # via pytest From 8b390027b99204c258a334bbce0f046b03aabeac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 11:08:06 +0000 Subject: [PATCH 18/39] Bump actions/cache from 4.2.0 to 4.2.1 (#10472) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/cache](https://github.com/actions/cache) from 4.2.0 to 4.2.1.
Release notes

Sourced from actions/cache's releases.

v4.2.1

What's Changed

[!IMPORTANT] As a reminder, there were important backend changes to release v4.2.0, see those release notes and the announcement for more details.

New Contributors

Full Changelog: https://github.com/actions/cache/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/cache's changelog.

4.2.1

  • Bump @actions/cache to v4.0.1
Commits
  • 0c907a7 Merge pull request #1554 from actions/robherley/v4.2.1
  • 710893c bump @​actions/cache to v4.0.1
  • 9fa7e61 Update force deletion docs due a recent deprecation (#1500)
  • 36f1e14 docs: Make the "always save prime numbers" example more clear (#1525)
  • 53aa38c Correct GitHub Spelling in caching-strategies.md (#1526)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/cache&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-cd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a794dc65d77..95f9fc7c631 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -47,7 +47,7 @@ jobs: with: python-version: 3.11 - name: Cache PyPI - uses: actions/cache@v4.2.0 + uses: actions/cache@v4.2.1 with: key: pip-lint-${{ hashFiles('requirements/*.txt') }} path: ~/.cache/pip @@ -99,7 +99,7 @@ jobs: with: submodules: true - name: Cache llhttp generated files - uses: actions/cache@v4.2.0 + uses: actions/cache@v4.2.1 id: cache with: key: llhttp-${{ hashFiles('vendor/llhttp/package*.json', 'vendor/llhttp/src/**/*') }} @@ -163,7 +163,7 @@ jobs: echo "dir=$(pip cache dir)" >> "${GITHUB_OUTPUT}" shell: bash - name: Cache PyPI - uses: actions/cache@v4.2.0 + uses: actions/cache@v4.2.1 with: key: pip-ci-${{ runner.os }}-${{ matrix.pyver }}-${{ matrix.no-extensions }}-${{ hashFiles('requirements/*.txt') }} path: ${{ steps.pip-cache.outputs.dir }} From 79c5093dc119ca29070200db9db69e324d5c0e65 Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Fri, 21 Feb 2025 02:52:59 +0800 Subject: [PATCH 19/39] [PR #10434/ed84464 backport][3.11] Fix inappropriate "break in finally" (#10476) --- CHANGES/10434.bugfix.rst | 2 ++ aiohttp/web_protocol.py | 28 +++++++++++++++------------- tests/test_web_server.py | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 CHANGES/10434.bugfix.rst diff --git a/CHANGES/10434.bugfix.rst b/CHANGES/10434.bugfix.rst new file mode 100644 index 00000000000..c4bc50dc6aa --- /dev/null +++ b/CHANGES/10434.bugfix.rst @@ -0,0 +1,2 @@ +Avoid break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler` +-- by :user:`Cycloctane`. diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index 32f503474a9..e4c347e5a9e 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -608,26 +608,28 @@ async def start(self) -> None: except asyncio.CancelledError: self.log_debug("Ignored premature client disconnection") + self.force_close() raise except Exception as exc: self.log_exception("Unhandled exception", exc_info=exc) self.force_close() + except BaseException: + self.force_close() + raise finally: if self.transport is None and resp is not None: self.log_debug("Ignored premature client disconnection.") - elif not self._force_close: - if self._keepalive and not self._close: - # start keep-alive timer - if keepalive_timeout is not None: - now = loop.time() - close_time = now + keepalive_timeout - self._next_keepalive_close_time = close_time - if self._keepalive_handle is None: - self._keepalive_handle = loop.call_at( - close_time, self._process_keepalive - ) - else: - break + + if self._keepalive and not self._close and not self._force_close: + # start keep-alive timer + close_time = loop.time() + keepalive_timeout + self._next_keepalive_close_time = close_time + if self._keepalive_handle is None: + self._keepalive_handle = loop.call_at( + close_time, self._process_keepalive + ) + else: + break # remove handler, close transport if no handlers left if not self._force_close: diff --git a/tests/test_web_server.py b/tests/test_web_server.py index 910f074e90f..9098ef9e7bf 100644 --- a/tests/test_web_server.py +++ b/tests/test_web_server.py @@ -233,6 +233,24 @@ async def handler(request): logger.debug.assert_called_with("Ignored premature client disconnection") +async def test_raw_server_does_not_swallow_base_exceptions( + aiohttp_raw_server: AiohttpRawServer, aiohttp_client: AiohttpClient +) -> None: + class UnexpectedException(BaseException): + """Dummy base exception.""" + + async def handler(request: web.BaseRequest) -> NoReturn: + raise UnexpectedException() + + loop = asyncio.get_event_loop() + loop.set_debug(True) + server = await aiohttp_raw_server(handler) + cli = await aiohttp_client(server) + + with pytest.raises(client.ServerDisconnectedError): + await cli.get("/path/to", timeout=client.ClientTimeout(10)) + + async def test_raw_server_cancelled_in_write_eof(aiohttp_raw_server, aiohttp_client): async def handler(request): resp = web.Response(text=str(request.rel_url)) From 9f933bffe6e1ed3a09afe360bf1fc0ca0a6e0107 Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Fri, 21 Feb 2025 03:03:24 +0800 Subject: [PATCH 20/39] [PR #10434/ed84464 backport][3.12] Fix inappropriate "break in finally" (#10475) --- CHANGES/10434.bugfix.rst | 2 ++ aiohttp/web_protocol.py | 28 +++++++++++++++------------- tests/test_web_server.py | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 CHANGES/10434.bugfix.rst diff --git a/CHANGES/10434.bugfix.rst b/CHANGES/10434.bugfix.rst new file mode 100644 index 00000000000..c4bc50dc6aa --- /dev/null +++ b/CHANGES/10434.bugfix.rst @@ -0,0 +1,2 @@ +Avoid break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler` +-- by :user:`Cycloctane`. diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index 32f503474a9..e4c347e5a9e 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -608,26 +608,28 @@ async def start(self) -> None: except asyncio.CancelledError: self.log_debug("Ignored premature client disconnection") + self.force_close() raise except Exception as exc: self.log_exception("Unhandled exception", exc_info=exc) self.force_close() + except BaseException: + self.force_close() + raise finally: if self.transport is None and resp is not None: self.log_debug("Ignored premature client disconnection.") - elif not self._force_close: - if self._keepalive and not self._close: - # start keep-alive timer - if keepalive_timeout is not None: - now = loop.time() - close_time = now + keepalive_timeout - self._next_keepalive_close_time = close_time - if self._keepalive_handle is None: - self._keepalive_handle = loop.call_at( - close_time, self._process_keepalive - ) - else: - break + + if self._keepalive and not self._close and not self._force_close: + # start keep-alive timer + close_time = loop.time() + keepalive_timeout + self._next_keepalive_close_time = close_time + if self._keepalive_handle is None: + self._keepalive_handle = loop.call_at( + close_time, self._process_keepalive + ) + else: + break # remove handler, close transport if no handlers left if not self._force_close: diff --git a/tests/test_web_server.py b/tests/test_web_server.py index 910f074e90f..9098ef9e7bf 100644 --- a/tests/test_web_server.py +++ b/tests/test_web_server.py @@ -233,6 +233,24 @@ async def handler(request): logger.debug.assert_called_with("Ignored premature client disconnection") +async def test_raw_server_does_not_swallow_base_exceptions( + aiohttp_raw_server: AiohttpRawServer, aiohttp_client: AiohttpClient +) -> None: + class UnexpectedException(BaseException): + """Dummy base exception.""" + + async def handler(request: web.BaseRequest) -> NoReturn: + raise UnexpectedException() + + loop = asyncio.get_event_loop() + loop.set_debug(True) + server = await aiohttp_raw_server(handler) + cli = await aiohttp_client(server) + + with pytest.raises(client.ServerDisconnectedError): + await cli.get("/path/to", timeout=client.ClientTimeout(10)) + + async def test_raw_server_cancelled_in_write_eof(aiohttp_raw_server, aiohttp_client): async def handler(request): resp = web.Response(text=str(request.rel_url)) From b7187a8f83c2ef8daaee23363bd2d29b851378e1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 19:55:14 +0000 Subject: [PATCH 21/39] [PR #10464/182198fc backport][3.11] Close the socket if there's a failure in start_connection() (#10477) Co-authored-by: Andrew Top <142360808+top-oai@users.noreply.github.com> --- CHANGES/10464.bugfix.rst | 1 + CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 13 ++++++++++++- tests/conftest.py | 1 + tests/test_connector.py | 23 +++++++++++++++++++++++ tests/test_proxy.py | 1 + 6 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10464.bugfix.rst diff --git a/CHANGES/10464.bugfix.rst b/CHANGES/10464.bugfix.rst new file mode 100644 index 00000000000..4e21000a317 --- /dev/null +++ b/CHANGES/10464.bugfix.rst @@ -0,0 +1 @@ +Changed connection creation to explicitly close sockets if an exception is raised in the event loop's ``create_connection`` method -- by :user:`top-oai`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index fb1b87ccc9d..1f0d1e7d2d7 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -42,6 +42,7 @@ Andrej Antonov Andrew Leech Andrew Lytvyn Andrew Svetlov +Andrew Top Andrew Zhou Andrii Soldatenko Anes Abismail diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 7e0986df657..14433ba37e1 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1108,6 +1108,7 @@ async def _wrap_create_connection( client_error: Type[Exception] = ClientConnectorError, **kwargs: Any, ) -> Tuple[asyncio.Transport, ResponseHandler]: + sock: Union[socket.socket, None] = None try: async with ceil_timeout( timeout.sock_connect, ceil_threshold=timeout.ceil_threshold @@ -1119,7 +1120,11 @@ async def _wrap_create_connection( interleave=self._interleave, loop=self._loop, ) - return await self._loop.create_connection(*args, **kwargs, sock=sock) + connection = await self._loop.create_connection( + *args, **kwargs, sock=sock + ) + sock = None + return connection except cert_errors as exc: raise ClientConnectorCertificateError(req.connection_key, exc) from exc except ssl_errors as exc: @@ -1128,6 +1133,12 @@ async def _wrap_create_connection( if exc.errno is None and isinstance(exc, asyncio.TimeoutError): raise raise client_error(req.connection_key, exc) from exc + finally: + if sock is not None: + # Will be hit if an exception is thrown before the event loop takes the socket. + # In that case, proactively close the socket to guard against event loop leaks. + # For example, see https://github.com/MagicStack/uvloop/issues/653. + sock.close() async def _wrap_existing_connection( self, diff --git a/tests/conftest.py b/tests/conftest.py index 44ae384b633..95a98cd4fc0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -221,6 +221,7 @@ def start_connection(): "aiohttp.connector.aiohappyeyeballs.start_connection", autospec=True, spec_set=True, + return_value=mock.create_autospec(socket.socket, spec_set=True, instance=True), ) as start_connection_mock: yield start_connection_mock diff --git a/tests/test_connector.py b/tests/test_connector.py index 483759a4180..e79b36a673d 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -617,6 +617,29 @@ async def certificate_error(*args, **kwargs): await conn.close() +async def test_tcp_connector_closes_socket_on_error( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + + conn = aiohttp.TCPConnector() + with ( + mock.patch.object( + conn._loop, + "create_connection", + autospec=True, + spec_set=True, + side_effect=ValueError, + ), + pytest.raises(ValueError), + ): + await conn.connect(req, [], ClientTimeout()) + + assert start_connection.return_value.close.called + + await conn.close() + + async def test_tcp_connector_server_hostname_default( loop: Any, start_connection: mock.AsyncMock ) -> None: diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 1679b68909f..83457de891f 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -207,6 +207,7 @@ async def make_conn(): "aiohttp.connector.aiohappyeyeballs.start_connection", autospec=True, spec_set=True, + return_value=mock.create_autospec(socket.socket, spec_set=True, instance=True), ) def test_proxy_connection_error(self, start_connection: Any) -> None: async def make_conn(): From a9c8841d62926debef7a876bb8e5a1ee6a180cf8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:38:57 +0000 Subject: [PATCH 22/39] [PR #10464/182198fc backport][3.12] Close the socket if there's a failure in start_connection() (#10478) Co-authored-by: Andrew Top <142360808+top-oai@users.noreply.github.com> --- CHANGES/10464.bugfix.rst | 1 + CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 13 ++++++++++++- tests/conftest.py | 1 + tests/test_connector.py | 23 +++++++++++++++++++++++ tests/test_proxy.py | 1 + 6 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10464.bugfix.rst diff --git a/CHANGES/10464.bugfix.rst b/CHANGES/10464.bugfix.rst new file mode 100644 index 00000000000..4e21000a317 --- /dev/null +++ b/CHANGES/10464.bugfix.rst @@ -0,0 +1 @@ +Changed connection creation to explicitly close sockets if an exception is raised in the event loop's ``create_connection`` method -- by :user:`top-oai`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 7eb48579097..a2511e95511 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -42,6 +42,7 @@ Andrej Antonov Andrew Leech Andrew Lytvyn Andrew Svetlov +Andrew Top Andrew Zhou Andrii Soldatenko Anes Abismail diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 7e0986df657..14433ba37e1 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1108,6 +1108,7 @@ async def _wrap_create_connection( client_error: Type[Exception] = ClientConnectorError, **kwargs: Any, ) -> Tuple[asyncio.Transport, ResponseHandler]: + sock: Union[socket.socket, None] = None try: async with ceil_timeout( timeout.sock_connect, ceil_threshold=timeout.ceil_threshold @@ -1119,7 +1120,11 @@ async def _wrap_create_connection( interleave=self._interleave, loop=self._loop, ) - return await self._loop.create_connection(*args, **kwargs, sock=sock) + connection = await self._loop.create_connection( + *args, **kwargs, sock=sock + ) + sock = None + return connection except cert_errors as exc: raise ClientConnectorCertificateError(req.connection_key, exc) from exc except ssl_errors as exc: @@ -1128,6 +1133,12 @@ async def _wrap_create_connection( if exc.errno is None and isinstance(exc, asyncio.TimeoutError): raise raise client_error(req.connection_key, exc) from exc + finally: + if sock is not None: + # Will be hit if an exception is thrown before the event loop takes the socket. + # In that case, proactively close the socket to guard against event loop leaks. + # For example, see https://github.com/MagicStack/uvloop/issues/653. + sock.close() async def _wrap_existing_connection( self, diff --git a/tests/conftest.py b/tests/conftest.py index 44ae384b633..95a98cd4fc0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -221,6 +221,7 @@ def start_connection(): "aiohttp.connector.aiohappyeyeballs.start_connection", autospec=True, spec_set=True, + return_value=mock.create_autospec(socket.socket, spec_set=True, instance=True), ) as start_connection_mock: yield start_connection_mock diff --git a/tests/test_connector.py b/tests/test_connector.py index 483759a4180..e79b36a673d 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -617,6 +617,29 @@ async def certificate_error(*args, **kwargs): await conn.close() +async def test_tcp_connector_closes_socket_on_error( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + + conn = aiohttp.TCPConnector() + with ( + mock.patch.object( + conn._loop, + "create_connection", + autospec=True, + spec_set=True, + side_effect=ValueError, + ), + pytest.raises(ValueError), + ): + await conn.connect(req, [], ClientTimeout()) + + assert start_connection.return_value.close.called + + await conn.close() + + async def test_tcp_connector_server_hostname_default( loop: Any, start_connection: mock.AsyncMock ) -> None: diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 1679b68909f..83457de891f 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -207,6 +207,7 @@ async def make_conn(): "aiohttp.connector.aiohappyeyeballs.start_connection", autospec=True, spec_set=True, + return_value=mock.create_autospec(socket.socket, spec_set=True, instance=True), ) def test_proxy_connection_error(self, start_connection: Any) -> None: async def make_conn(): From d896b2104d557776c3816c49a2ae017d8e59a2bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:39:02 +0000 Subject: [PATCH 23/39] Bump proxy-py from 2.4.9 to 2.4.10 (#10471) Bumps [proxy-py](https://github.com/abhinavsingh/proxy.py) from 2.4.9 to 2.4.10.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proxy-py&package-manager=pip&previous-version=2.4.9&new-version=2.4.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/test.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 9cd66c31096..60b86c6df53 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -136,7 +136,7 @@ propcache==0.2.1 # via # -r requirements/runtime-deps.in # yarl -proxy-py==2.4.9 +proxy-py==2.4.10 # via -r requirements/test.in pycares==4.5.0 # via aiodns diff --git a/requirements/dev.txt b/requirements/dev.txt index e97b52d4c97..8c1c027cc09 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -133,7 +133,7 @@ propcache==0.2.1 # via # -r requirements/runtime-deps.in # yarl -proxy-py==2.4.9 +proxy-py==2.4.10 # via -r requirements/test.in pycares==4.5.0 # via aiodns diff --git a/requirements/test.txt b/requirements/test.txt index 791bc28e9b4..5ee3a0751b3 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -71,7 +71,7 @@ propcache==0.2.1 # via # -r requirements/runtime-deps.in # yarl -proxy-py==2.4.9 +proxy-py==2.4.10 # via -r requirements/test.in pycares==4.5.0 # via aiodns From ae6220671b65064bc84909f62a0fa423eb0f6595 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:39:04 +0000 Subject: [PATCH 24/39] Bump coverage from 7.6.11 to 7.6.12 (#10462) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.11 to 7.6.12.
Changelog

Sourced from coverage's changelog.

Version 7.6.12 — 2025-02-11

  • Fix: some aarch64 distributions were missing (issue 1927_). These are now building reliably.

.. _issue 1927: nedbat/coveragepy#1927

.. _changes_7-6-11:

Commits
  • 7e5373e docs: sample HTML for 7.6.12
  • a4ed38b docs: prep for 7.6.12
  • ce4efdc build: fix aarch64 kits #1927
  • a1f3192 build: don't publish if kit building failed
  • bb68f99 chore: bump the action-dependencies group with 2 updates (#1926)
  • f3d6b4a refactor: check for more kinds of constant tests
  • 67899ea refactor: we no longer care what kind of constant the compile-time constants are
  • c850f20 refactor: macOS is MACOS, not OSX
  • a1b2c1a build: there are always tweaks to howto.txt
  • 9c03039 build: bump version to 7.6.12
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=coverage&package-manager=pip&previous-version=7.6.11&new-version=7.6.12)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/test.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 60b86c6df53..97ecbb8cef5 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -50,7 +50,7 @@ click==8.1.8 # slotscheck # towncrier # wait-for-it -coverage==7.6.11 +coverage==7.6.12 # via # -r requirements/test.in # pytest-cov diff --git a/requirements/dev.txt b/requirements/dev.txt index 8c1c027cc09..29e90f1cf51 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -50,7 +50,7 @@ click==8.1.8 # slotscheck # towncrier # wait-for-it -coverage==7.6.11 +coverage==7.6.12 # via # -r requirements/test.in # pytest-cov diff --git a/requirements/test.txt b/requirements/test.txt index 5ee3a0751b3..9e089d12363 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -25,7 +25,7 @@ cffi==1.17.1 # pytest-codspeed click==8.1.8 # via wait-for-it -coverage==7.6.11 +coverage==7.6.12 # via # -r requirements/test.in # pytest-cov From be1159b823703047377348d6f84dfe8165c8bfb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:45:48 +0000 Subject: [PATCH 25/39] Bump identify from 2.6.6 to 2.6.7 (#10443) Bumps [identify](https://github.com/pre-commit/identify) from 2.6.6 to 2.6.7.
Commits
  • 157ee8e v2.6.7
  • 76cf716 Merge pull request #503 from mheiges/uv-interpreter
  • 8130ef9 add uv to interpreters list
  • e09b689 Merge pull request #501 from dinoshauer/patch-1
  • 5a2b68b add .templ extension
  • 4db44f0 Merge pull request #504 from pre-commit/all-repos_autofix_all-repos-sed
  • 82ab282 upgrade asottile/workflows
  • 96281e4 Merge pull request #502 from pre-commit/pre-commit-ci-update-config
  • 94c5fb1 [pre-commit.ci] pre-commit autoupdate
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=identify&package-manager=pip&previous-version=2.6.6&new-version=2.6.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 97ecbb8cef5..9955dfc0747 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -82,7 +82,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.6 +identify==2.6.7 # via pre-commit idna==3.3 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index 29e90f1cf51..a3b06a8ab8a 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -80,7 +80,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.6 +identify==2.6.7 # via pre-commit idna==3.4 # via diff --git a/requirements/lint.txt b/requirements/lint.txt index 57fdc34c119..616639a8508 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -29,7 +29,7 @@ filelock==3.17.0 # via virtualenv freezegun==1.5.1 # via -r requirements/lint.in -identify==2.6.6 +identify==2.6.7 # via pre-commit idna==3.7 # via trustme From af48c8dbb0a11e022c08a88630fc0b93f7970f22 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Fri, 21 Feb 2025 01:18:09 +0100 Subject: [PATCH 26/39] [PR #10433/0c4b1c7 backport][3.12] Detect blocking calls in coroutines using BlockBuster (#10480) --- CHANGES/10433.feature.rst | 1 + CONTRIBUTORS.txt | 1 + aiohttp/client.py | 9 ++- requirements/lint.in | 1 + requirements/lint.txt | 4 ++ requirements/test.in | 1 + requirements/test.txt | 4 ++ tests/conftest.py | 31 +++++++++++ tests/test_client_functional.py | 97 +++++++++++++++++---------------- tests/test_cookiejar.py | 2 +- tests/test_web_functional.py | 28 +++++----- 11 files changed, 113 insertions(+), 66 deletions(-) create mode 100644 CHANGES/10433.feature.rst diff --git a/CHANGES/10433.feature.rst b/CHANGES/10433.feature.rst new file mode 100644 index 00000000000..11a29d6e368 --- /dev/null +++ b/CHANGES/10433.feature.rst @@ -0,0 +1 @@ +Detect blocking calls in coroutines using BlockBuster -- by :user:`cbornet`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index a2511e95511..9dd9d873003 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -80,6 +80,7 @@ Chris AtLee Chris Laws Chris Moore Chris Shucksmith +Christophe Bornet Christopher Schmitt Claudiu Popa Colin Dunklau diff --git a/aiohttp/client.py b/aiohttp/client.py index 2d5a9a4cdce..8ba5e282e2c 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -664,11 +664,14 @@ async def _request( if req_cookies: all_cookies.load(req_cookies) + proxy_: Optional[URL] = None if proxy is not None: - proxy = URL(proxy) + proxy_ = URL(proxy) elif self._trust_env: with suppress(LookupError): - proxy, proxy_auth = get_env_proxy_for_url(url) + proxy_, proxy_auth = await asyncio.to_thread( + get_env_proxy_for_url, url + ) req = self._request_class( method, @@ -685,7 +688,7 @@ async def _request( expect100=expect100, loop=self._loop, response_class=self._response_class, - proxy=proxy, + proxy=proxy_, proxy_auth=proxy_auth, timer=timer, session=self, diff --git a/requirements/lint.in b/requirements/lint.in index 04eea1408da..4759dadc6a9 100644 --- a/requirements/lint.in +++ b/requirements/lint.in @@ -1,4 +1,5 @@ aiodns +blockbuster freezegun mypy; implementation_name == "cpython" pre-commit diff --git a/requirements/lint.txt b/requirements/lint.txt index 616639a8508..fd5a757b7b8 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -10,6 +10,8 @@ annotated-types==0.7.0 # via pydantic async-timeout==5.0.1 # via valkey +blockbuster==1.5.21 + # via -r requirements/lint.in cffi==1.17.1 # via # cryptography @@ -27,6 +29,8 @@ exceptiongroup==1.2.2 # via pytest filelock==3.17.0 # via virtualenv +forbiddenfruit==0.1.4 + # via blockbuster freezegun==1.5.1 # via -r requirements/lint.in identify==2.6.7 diff --git a/requirements/test.in b/requirements/test.in index 6686b373758..c6547bee5e5 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -1,5 +1,6 @@ -r base.in +blockbuster coverage freezegun mypy; implementation_name == "cpython" diff --git a/requirements/test.txt b/requirements/test.txt index 9e089d12363..e3e1c11e5bb 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -16,6 +16,8 @@ async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in attrs==25.1.0 # via -r requirements/runtime-deps.in +blockbuster==1.5.21 + # via -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in cffi==1.17.1 @@ -35,6 +37,8 @@ exceptiongroup==1.2.2 # via pytest execnet==2.1.1 # via pytest-xdist +forbiddenfruit==0.1.4 + # via blockbuster freezegun==1.5.1 # via -r requirements/test.in frozenlist==1.5.0 diff --git a/tests/conftest.py b/tests/conftest.py index 95a98cd4fc0..f7b3dcdb752 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -12,6 +12,7 @@ from uuid import uuid4 import pytest +from blockbuster import blockbuster_ctx from aiohttp.client_proto import ResponseHandler from aiohttp.http import WS_KEY @@ -33,6 +34,36 @@ IS_LINUX = sys.platform.startswith("linux") +@pytest.fixture(autouse=True) +def blockbuster(request): + # No blockbuster for benchmark tests. + node = request.node.parent + while node: + if node.name.startswith("test_benchmarks"): + yield + return + node = node.parent + with blockbuster_ctx( + "aiohttp", excluded_modules=["aiohttp.pytest_plugin", "aiohttp.test_utils"] + ) as bb: + # TODO: Fix blocking call in ClientRequest's constructor. + # https://github.com/aio-libs/aiohttp/issues/10435 + for func in ["io.TextIOWrapper.read", "os.stat"]: + bb.functions[func].can_block_in("aiohttp/client_reqrep.py", "update_auth") + for func in [ + "os.getcwd", + "os.readlink", + "os.stat", + "os.path.abspath", + "os.path.samestat", + ]: + bb.functions[func].can_block_in( + "aiohttp/web_urldispatcher.py", "add_static" + ) + bb.functions["os.getcwd"].can_block_in("coverage/control.py", "_should_trace") + yield + + @pytest.fixture def tls_certificate_authority(): if not TRUSTME: diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index ba75e8e93c6..9ffe5f523f3 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -477,7 +477,7 @@ async def test_post_data_with_bytesio_file(aiohttp_client) -> None: async def handler(request): post_data = await request.post() assert ["file"] == list(post_data.keys()) - assert data == post_data["file"].file.read() + assert data == await asyncio.to_thread(post_data["file"].file.read) post_data["file"].file.close() # aiohttp < 4 doesn't autoclose files return web.Response() @@ -1595,14 +1595,14 @@ async def handler(request: web.Request) -> web.Response: async def test_POST_FILES(aiohttp_client, fname) -> None: + content1 = fname.read_bytes() + async def handler(request): data = await request.post() assert data["some"].filename == fname.name - with fname.open("rb") as f: - content1 = f.read() - content2 = data["some"].file.read() - assert content1 == content2 - assert data["test"].file.read() == b"data" + content2 = await asyncio.to_thread(data["some"].file.read) + assert content2 == content1 + assert await asyncio.to_thread(data["test"].file.read) == b"data" data["some"].file.close() data["test"].file.close() return web.Response() @@ -1619,14 +1619,14 @@ async def handler(request): async def test_POST_FILES_DEFLATE(aiohttp_client, fname) -> None: + content1 = fname.read_bytes() + async def handler(request): data = await request.post() assert data["some"].filename == fname.name - with fname.open("rb") as f: - content1 = f.read() - content2 = data["some"].file.read() + content2 = await asyncio.to_thread(data["some"].file.read) data["some"].file.close() - assert content1 == content2 + assert content2 == content1 return web.Response() app = web.Application() @@ -1676,12 +1676,12 @@ async def handler(request): async def test_POST_FILES_STR(aiohttp_client, fname) -> None: + content1 = fname.read_bytes().decode() + async def handler(request): data = await request.post() - with fname.open("rb") as f: - content1 = f.read().decode() content2 = data["some"] - assert content1 == content2 + assert content2 == content1 return web.Response() app = web.Application() @@ -1694,11 +1694,11 @@ async def handler(request): async def test_POST_FILES_STR_SIMPLE(aiohttp_client, fname) -> None: + content = fname.read_bytes() + async def handler(request): data = await request.read() - with fname.open("rb") as f: - content = f.read() - assert content == data + assert data == content return web.Response() app = web.Application() @@ -1711,12 +1711,12 @@ async def handler(request): async def test_POST_FILES_LIST(aiohttp_client, fname) -> None: + content = fname.read_bytes() + async def handler(request): data = await request.post() assert fname.name == data["some"].filename - with fname.open("rb") as f: - content = f.read() - assert content == data["some"].file.read() + assert await asyncio.to_thread(data["some"].file.read) == content data["some"].file.close() return web.Response() @@ -1730,13 +1730,13 @@ async def handler(request): async def test_POST_FILES_CT(aiohttp_client, fname) -> None: + content = fname.read_bytes() + async def handler(request): data = await request.post() assert fname.name == data["some"].filename assert "text/plain" == data["some"].content_type - with fname.open("rb") as f: - content = f.read() - assert content == data["some"].file.read() + assert await asyncio.to_thread(data["some"].file.read) == content data["some"].file.close() return web.Response() @@ -1752,11 +1752,11 @@ async def handler(request): async def test_POST_FILES_SINGLE(aiohttp_client, fname) -> None: + content = fname.read_bytes().decode() + async def handler(request): data = await request.text() - with fname.open("rb") as f: - content = f.read().decode() - assert content == data + assert data == content # if system cannot determine 'text/x-python' MIME type # then use 'application/octet-stream' default assert request.content_type in [ @@ -1778,11 +1778,11 @@ async def handler(request): async def test_POST_FILES_SINGLE_content_disposition(aiohttp_client, fname) -> None: + content = fname.read_bytes().decode() + async def handler(request): data = await request.text() - with fname.open("rb") as f: - content = f.read().decode() - assert content == data + assert data == content # if system cannot determine 'application/pgp-keys' MIME type # then use 'application/octet-stream' default assert request.content_type in [ @@ -1808,11 +1808,11 @@ async def handler(request): async def test_POST_FILES_SINGLE_BINARY(aiohttp_client, fname) -> None: + content = fname.read_bytes() + async def handler(request): data = await request.read() - with fname.open("rb") as f: - content = f.read() - assert content == data + assert data == content # if system cannot determine 'application/pgp-keys' MIME type # then use 'application/octet-stream' default assert request.content_type in [ @@ -1835,7 +1835,7 @@ async def handler(request): async def test_POST_FILES_IO(aiohttp_client) -> None: async def handler(request): data = await request.post() - assert b"data" == data["unknown"].file.read() + assert b"data" == await asyncio.to_thread(data["unknown"].file.read) assert data["unknown"].content_type == "application/octet-stream" assert data["unknown"].filename == "unknown" data["unknown"].file.close() @@ -1856,7 +1856,7 @@ async def handler(request): assert data["test"] == "true" assert data["unknown"].content_type == "application/octet-stream" assert data["unknown"].filename == "unknown" - assert data["unknown"].file.read() == b"data" + assert await asyncio.to_thread(data["unknown"].file.read) == b"data" data["unknown"].file.close() assert data.getall("q") == ["t1", "t2"] @@ -1875,6 +1875,8 @@ async def handler(request): async def test_POST_FILES_WITH_DATA(aiohttp_client, fname) -> None: + content = fname.read_bytes() + async def handler(request): data = await request.post() assert data["test"] == "true" @@ -1884,9 +1886,8 @@ async def handler(request): "application/octet-stream", ] assert data["some"].filename == fname.name - with fname.open("rb") as f: - assert data["some"].file.read() == f.read() - data["some"].file.close() + assert await asyncio.to_thread(data["some"].file.read) == content + data["some"].file.close() return web.Response() @@ -1900,13 +1901,13 @@ async def handler(request): async def test_POST_STREAM_DATA(aiohttp_client, fname) -> None: + expected = fname.read_bytes() + async def handler(request): assert request.content_type == "application/octet-stream" content = await request.read() - with fname.open("rb") as f: - expected = f.read() - assert request.content_length == len(expected) - assert content == expected + assert request.content_length == len(expected) + assert content == expected return web.Response() @@ -1922,10 +1923,10 @@ async def handler(request): @aiohttp.streamer async def stream(writer, fname): with fname.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: await writer.write(data) - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async with client.post( "/", data=stream(fname), headers={"Content-Length": str(data_size)} @@ -1934,13 +1935,13 @@ async def stream(writer, fname): async def test_POST_STREAM_DATA_no_params(aiohttp_client, fname) -> None: + expected = fname.read_bytes() + async def handler(request): assert request.content_type == "application/octet-stream" content = await request.read() - with fname.open("rb") as f: - expected = f.read() - assert request.content_length == len(expected) - assert content == expected + assert request.content_length == len(expected) + assert content == expected return web.Response() @@ -1956,10 +1957,10 @@ async def handler(request): @aiohttp.streamer async def stream(writer): with fname.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: await writer.write(data) - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async with client.post( "/", data=stream, headers={"Content-Length": str(data_size)} diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py index 0b440bc2ca6..4c37e962597 100644 --- a/tests/test_cookiejar.py +++ b/tests/test_cookiejar.py @@ -179,7 +179,7 @@ async def test_constructor_with_expired( assert jar._loop is loop -async def test_save_load(tmp_path, loop, cookies_to_send, cookies_to_receive) -> None: +def test_save_load(tmp_path, loop, cookies_to_send, cookies_to_receive) -> None: file_path = pathlib.Path(str(tmp_path)) / "aiohttp.test.cookie" # export cookie jar diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py index e4979851300..47189f7460b 100644 --- a/tests/test_web_functional.py +++ b/tests/test_web_functional.py @@ -403,7 +403,7 @@ async def handler(request): data = await request.post() assert ["data.unknown_mime_type"] == list(data.keys()) for fs in data.values(): - check_file(fs) + await asyncio.to_thread(check_file, fs) fs.file.close() resp = web.Response(body=b"OK") return resp @@ -429,9 +429,9 @@ async def handler(request): for _file in files: assert not _file.file.closed if _file.filename == "test1.jpeg": - assert _file.file.read() == b"binary data 1" + assert await asyncio.to_thread(_file.file.read) == b"binary data 1" if _file.filename == "test2.jpeg": - assert _file.file.read() == b"binary data 2" + assert await asyncio.to_thread(_file.file.read) == b"binary data 2" file_names.add(_file.filename) _file.file.close() assert len(files) == 2 @@ -471,7 +471,7 @@ async def handler(request): data = await request.post() assert ["data.unknown_mime_type", "conftest.py"] == list(data.keys()) for fs in data.values(): - check_file(fs) + await asyncio.to_thread(check_file, fs) fs.file.close() resp = web.Response(body=b"OK") return resp @@ -757,7 +757,7 @@ async def test_upload_file(aiohttp_client) -> None: async def handler(request): form = await request.post() - raw_data = form["file"].file.read() + raw_data = await asyncio.to_thread(form["file"].file.read) form["file"].file.close() assert data == raw_data return web.Response() @@ -780,7 +780,7 @@ async def test_upload_file_object(aiohttp_client) -> None: async def handler(request): form = await request.post() - raw_data = form["file"].file.read() + raw_data = await asyncio.to_thread(form["file"].file.read) form["file"].file.close() assert data == raw_data return web.Response() @@ -906,10 +906,10 @@ async def test_response_with_async_gen(aiohttp_client, fname) -> None: async def stream(f_name): with f_name.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: yield data - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async def handler(request): headers = {"Content-Length": str(data_size)} @@ -940,10 +940,10 @@ async def test_response_with_streamer(aiohttp_client, fname) -> None: @aiohttp.streamer async def stream(writer, f_name): with f_name.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: await writer.write(data) - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async def handler(request): headers = {"Content-Length": str(data_size)} @@ -969,10 +969,10 @@ async def test_response_with_async_gen_no_params(aiohttp_client, fname) -> None: async def stream(): with fname.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: yield data - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async def handler(request): headers = {"Content-Length": str(data_size)} @@ -1003,10 +1003,10 @@ async def test_response_with_streamer_no_params(aiohttp_client, fname) -> None: @aiohttp.streamer async def stream(writer): with fname.open("rb") as f: - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) while data: await writer.write(data) - data = f.read(100) + data = await asyncio.to_thread(f.read, 100) async def handler(request): headers = {"Content-Length": str(data_size)} From 079a2424c9c5f76d2dffefbb9d6333b9e0ad5c98 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Fri, 21 Feb 2025 01:46:39 +0100 Subject: [PATCH 27/39] [PR #10481/60819de backport][3.12] Bump blockbuster to 1.5.22 (#10481) (#10482) --- requirements/lint.txt | 2 +- requirements/test.txt | 2 +- tests/conftest.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements/lint.txt b/requirements/lint.txt index fd5a757b7b8..a8195a21d4b 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -10,7 +10,7 @@ annotated-types==0.7.0 # via pydantic async-timeout==5.0.1 # via valkey -blockbuster==1.5.21 +blockbuster==1.5.22 # via -r requirements/lint.in cffi==1.17.1 # via diff --git a/requirements/test.txt b/requirements/test.txt index e3e1c11e5bb..fc607243bc2 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -16,7 +16,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in attrs==25.1.0 # via -r requirements/runtime-deps.in -blockbuster==1.5.21 +blockbuster==1.5.22 # via -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in diff --git a/tests/conftest.py b/tests/conftest.py index f7b3dcdb752..5bca52fe67c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -60,7 +60,6 @@ def blockbuster(request): bb.functions[func].can_block_in( "aiohttp/web_urldispatcher.py", "add_static" ) - bb.functions["os.getcwd"].can_block_in("coverage/control.py", "_should_trace") yield From 0704705ac58c7cfd113182881b1457ac42a4d745 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:57:07 +0000 Subject: [PATCH 28/39] Bump propcache from 0.2.1 to 0.3.0 (#10483) Bumps [propcache](https://github.com/aio-libs/propcache) from 0.2.1 to 0.3.0.
Release notes

Sourced from propcache's releases.

0.3.0

Features

  • Implemented support for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: #84.

Packaging updates and notes for downstreams

  • Started building wheels for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: #84.

Contributor-facing changes

  • GitHub Actions CI/CD is now configured to manage caching pip-ecosystem dependencies using re-actors/cache-python-deps_ -- an action by :user:webknjaz that takes into account ABI stability and the exact version of Python runtime.

    .. _re-actors/cache-python-deps: https://github.com/marketplace/actions/cache-python-deps

    Related issues and pull requests on GitHub: #93.


Changelog

Sourced from propcache's changelog.

0.3.0

(2025-02-20)

Features

  • Implemented support for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: :issue:84.

Packaging updates and notes for downstreams

  • Started building wheels for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: :issue:84.

Contributor-facing changes

  • GitHub Actions CI/CD is now configured to manage caching pip-ecosystem dependencies using re-actors/cache-python-deps_ -- an action by :user:webknjaz that takes into account ABI stability and the exact version of Python runtime.

    .. _re-actors/cache-python-deps: https://github.com/marketplace/actions/cache-python-deps

    Related issues and pull requests on GitHub: :issue:93.


Commits
  • 7b88cc0 Revert "Start building wheels for armv7l manylinux (#94)" (#98)
  • 3d74e2d Release 0.3.0 (#96)
  • 9f8918b Start building wheels for armv7l manylinux (#94)
  • 50155c3 Add qemu workaround to fix wheel builds (#95)
  • ccab7f4 Implement support for the free-threaded build of CPython 3.13 (#84)
  • f560940 Bump sphinx from 8.1.3 to 8.2.0 (#92)
  • f203f97 Bump cython from 3.0.11 to 3.0.12 (#91)
  • b67c178 Bump pytest-codspeed from 3.1.2 to 3.2.0 (#90)
  • 4fe87bc Switch caching to use re-actors/cache-python-deps (#93)
  • b8aeb2f Bump pre-commit from 4.0.1 to 4.1.0 (#88)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=propcache&package-manager=pip&previous-version=0.2.1&new-version=0.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/base.txt | 2 +- requirements/constraints.txt | 8 +++++++- requirements/dev.txt | 8 +++++++- requirements/runtime-deps.txt | 2 +- requirements/test.txt | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 45a1fac6fa4..fb7a1d43f43 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -32,7 +32,7 @@ multidict==6.1.0 # yarl packaging==24.2 # via gunicorn -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 9955dfc0747..adfdd34ce8d 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -26,6 +26,10 @@ attrs==25.1.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx +blockbuster==1.5.22 + # via + # -r requirements/lint.in + # -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in build==1.2.2.post1 @@ -70,6 +74,8 @@ execnet==2.1.1 # via pytest-xdist filelock==3.17.0 # via virtualenv +forbiddenfruit==0.1.4 + # via blockbuster freezegun==1.5.1 # via # -r requirements/lint.in @@ -132,7 +138,7 @@ pluggy==1.5.0 # via pytest pre-commit==4.1.0 # via -r requirements/lint.in -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/dev.txt b/requirements/dev.txt index a3b06a8ab8a..3d536fc0a41 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -26,6 +26,10 @@ attrs==25.1.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx +blockbuster==1.5.22 + # via + # -r requirements/lint.in + # -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in build==1.2.2.post1 @@ -68,6 +72,8 @@ execnet==2.1.1 # via pytest-xdist filelock==3.17.0 # via virtualenv +forbiddenfruit==0.1.4 + # via blockbuster freezegun==1.5.1 # via # -r requirements/lint.in @@ -129,7 +135,7 @@ pluggy==1.5.0 # via pytest pre-commit==4.1.0 # via -r requirements/lint.in -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/runtime-deps.txt b/requirements/runtime-deps.txt index 118f584b7dd..4265eab71a3 100644 --- a/requirements/runtime-deps.txt +++ b/requirements/runtime-deps.txt @@ -28,7 +28,7 @@ multidict==6.1.0 # via # -r requirements/runtime-deps.in # yarl -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/test.txt b/requirements/test.txt index fc607243bc2..2a71315b0f7 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -71,7 +71,7 @@ packaging==24.2 # pytest pluggy==1.5.0 # via pytest -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl From 1c114ac33980d50ce2594a4f5e37dbab993d0042 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:57:16 +0000 Subject: [PATCH 29/39] Bump propcache from 0.2.1 to 0.3.0 (#10484) Bumps [propcache](https://github.com/aio-libs/propcache) from 0.2.1 to 0.3.0.
Release notes

Sourced from propcache's releases.

0.3.0

Features

  • Implemented support for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: #84.

Packaging updates and notes for downstreams

  • Started building wheels for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: #84.

Contributor-facing changes

  • GitHub Actions CI/CD is now configured to manage caching pip-ecosystem dependencies using re-actors/cache-python-deps_ -- an action by :user:webknjaz that takes into account ABI stability and the exact version of Python runtime.

    .. _re-actors/cache-python-deps: https://github.com/marketplace/actions/cache-python-deps

    Related issues and pull requests on GitHub: #93.


Changelog

Sourced from propcache's changelog.

0.3.0

(2025-02-20)

Features

  • Implemented support for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: :issue:84.

Packaging updates and notes for downstreams

  • Started building wheels for the free-threaded build of CPython 3.13 -- by :user:lysnikolaou.

    Related issues and pull requests on GitHub: :issue:84.

Contributor-facing changes

  • GitHub Actions CI/CD is now configured to manage caching pip-ecosystem dependencies using re-actors/cache-python-deps_ -- an action by :user:webknjaz that takes into account ABI stability and the exact version of Python runtime.

    .. _re-actors/cache-python-deps: https://github.com/marketplace/actions/cache-python-deps

    Related issues and pull requests on GitHub: :issue:93.


Commits
  • 7b88cc0 Revert "Start building wheels for armv7l manylinux (#94)" (#98)
  • 3d74e2d Release 0.3.0 (#96)
  • 9f8918b Start building wheels for armv7l manylinux (#94)
  • 50155c3 Add qemu workaround to fix wheel builds (#95)
  • ccab7f4 Implement support for the free-threaded build of CPython 3.13 (#84)
  • f560940 Bump sphinx from 8.1.3 to 8.2.0 (#92)
  • f203f97 Bump cython from 3.0.11 to 3.0.12 (#91)
  • b67c178 Bump pytest-codspeed from 3.1.2 to 3.2.0 (#90)
  • 4fe87bc Switch caching to use re-actors/cache-python-deps (#93)
  • b8aeb2f Bump pre-commit from 4.0.1 to 4.1.0 (#88)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=propcache&package-manager=pip&previous-version=0.2.1&new-version=0.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/base.txt | 2 +- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/runtime-deps.txt | 2 +- requirements/test.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 49891cf5b39..22a0288cb5f 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -30,7 +30,7 @@ multidict==6.1.0 # yarl packaging==24.2 # via gunicorn -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 56de66cc419..8f95f6eed70 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -136,7 +136,7 @@ pluggy==1.5.0 # via pytest pre-commit==4.1.0 # via -r requirements/lint.in -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/dev.txt b/requirements/dev.txt index b6f1e849123..80b3d45896c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -133,7 +133,7 @@ pluggy==1.5.0 # via pytest pre-commit==4.1.0 # via -r requirements/lint.in -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/runtime-deps.txt b/requirements/runtime-deps.txt index 8ab8f3f43b9..75830bf4190 100644 --- a/requirements/runtime-deps.txt +++ b/requirements/runtime-deps.txt @@ -26,7 +26,7 @@ multidict==6.1.0 # via # -r requirements/runtime-deps.in # yarl -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl diff --git a/requirements/test.txt b/requirements/test.txt index c27b4271167..b5a04884fd8 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -69,7 +69,7 @@ packaging==24.2 # pytest pluggy==1.5.0 # via pytest -propcache==0.2.1 +propcache==0.3.0 # via # -r requirements/runtime-deps.in # yarl From e565ed598155fa2884d9c1241130fcf48986f4e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:06:10 +0000 Subject: [PATCH 30/39] Bump blockbuster from 1.5.21 to 1.5.22 (#10485) Bumps [blockbuster](https://github.com/cbornet/blockbuster) from 1.5.21 to 1.5.22.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=blockbuster&package-manager=pip&previous-version=1.5.21&new-version=1.5.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 8f95f6eed70..eba33f77d34 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # valkey babel==2.17.0 # via sphinx -blockbuster==1.5.21 +blockbuster==1.5.22 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 80b3d45896c..bd503228bb0 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # valkey babel==2.17.0 # via sphinx -blockbuster==1.5.21 +blockbuster==1.5.22 # via # -r requirements/lint.in # -r requirements/test.in From 7379a866bb9fa41986a01aa6fff2a73a210b66de Mon Sep 17 00:00:00 2001 From: Tim Menninger Date: Fri, 21 Feb 2025 13:19:27 -0800 Subject: [PATCH 31/39] Expose setsockopt in TCPConnector API (#10474) --- CHANGES/10474.feature.rst | 2 ++ CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 12 ++++++++++++ docs/client_advanced.rst | 15 +++++++++++++++ docs/client_reference.rst | 9 ++++++++- tests/test_connector.py | 23 +++++++++++++++++++++++ 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10474.feature.rst diff --git a/CHANGES/10474.feature.rst b/CHANGES/10474.feature.rst new file mode 100644 index 00000000000..d5d6e4b40b9 --- /dev/null +++ b/CHANGES/10474.feature.rst @@ -0,0 +1,2 @@ +Added ``tcp_sockopts`` to ``TCPConnector`` to allow specifying custom socket options +-- by :user:`TimMenninger`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 42062c972c8..3004ee5cd18 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -341,6 +341,7 @@ Thanos Lefteris Thijs Vermeir Thomas Forbes Thomas Grainger +Tim Menninger Tolga Tezel Tomasz Trebski Toshiaki Tanaka diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 99b281b24a5..8a3f1bcbf2b 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -20,6 +20,7 @@ DefaultDict, Deque, Dict, + Iterable, Iterator, List, Literal, @@ -61,6 +62,11 @@ ) from .resolver import DefaultResolver +if sys.version_info >= (3, 12): + from collections.abc import Buffer +else: + Buffer = Union[bytes, bytearray, "memoryview[int]", "memoryview[bytes]"] + if TYPE_CHECKING: import ssl @@ -820,6 +826,8 @@ class TCPConnector(BaseConnector): the happy eyeballs algorithm, set to None. interleave - “First Address Family Count” as defined in RFC 8305 loop - Optional event loop. + tcp_sockopts - List of tuples of sockopts applied to underlying + socket """ allowed_protocol_schema_set = HIGH_LEVEL_SCHEMA_SET | frozenset({"tcp"}) @@ -841,6 +849,7 @@ def __init__( timeout_ceil_threshold: float = 5, happy_eyeballs_delay: Optional[float] = 0.25, interleave: Optional[int] = None, + tcp_sockopts: Iterable[Tuple[int, int, Union[int, Buffer]]] = [], ): super().__init__( keepalive_timeout=keepalive_timeout, @@ -871,6 +880,7 @@ def __init__( self._happy_eyeballs_delay = happy_eyeballs_delay self._interleave = interleave self._resolve_host_tasks: Set["asyncio.Task[List[ResolveResult]]"] = set() + self._tcp_sockopts = tcp_sockopts def _close_immediately(self) -> List[Awaitable[object]]: for fut in chain.from_iterable(self._throttle_dns_futures.values()): @@ -1113,6 +1123,8 @@ async def _wrap_create_connection( interleave=self._interleave, loop=self._loop, ) + for sockopt in self._tcp_sockopts: + sock.setsockopt(*sockopt) connection = await self._loop.create_connection( *args, **kwargs, sock=sock ) diff --git a/docs/client_advanced.rst b/docs/client_advanced.rst index 01ea3e9dc73..8f34fefaf81 100644 --- a/docs/client_advanced.rst +++ b/docs/client_advanced.rst @@ -468,6 +468,21 @@ If your HTTP server uses UNIX domain sockets you can use session = aiohttp.ClientSession(connector=conn) +Setting socket options +^^^^^^^^^^^^^^^^^^^^^^ + +Socket options passed to the :class:`~aiohttp.TCPConnector` will be passed +to the underlying socket when creating a connection. For example, we may +want to change the conditions under which we consider a connection dead. +The following would change that to 9*7200 = 18 hours:: + + import socket + + conn = aiohttp.TCPConnector(tcp_sockopts=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True), + (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7200), + (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 9) ]) + + Named pipes in Windows ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/client_reference.rst b/docs/client_reference.rst index 8f15948f34b..e1128934631 100644 --- a/docs/client_reference.rst +++ b/docs/client_reference.rst @@ -1128,7 +1128,8 @@ is controlled by *force_close* constructor's parameter). resolver=None, keepalive_timeout=sentinel, \ force_close=False, limit=100, limit_per_host=0, \ enable_cleanup_closed=False, timeout_ceil_threshold=5, \ - happy_eyeballs_delay=0.25, interleave=None, loop=None) + happy_eyeballs_delay=0.25, interleave=None, loop=None, \ + tcp_sockopts=[]) Connector for working with *HTTP* and *HTTPS* via *TCP* sockets. @@ -1249,6 +1250,12 @@ is controlled by *force_close* constructor's parameter). .. versionadded:: 3.10 + :param list tcp_sockopts: options applied to the socket when a connection is + created. This should be a list of 3-tuples, each a ``(level, optname, value)``. + Each tuple is deconstructed and passed verbatim to ``.setsockopt``. + + .. versionadded:: 3.12 + .. attribute:: family *TCP* socket family e.g. :data:`socket.AF_INET` or diff --git a/tests/test_connector.py b/tests/test_connector.py index 80fb9ba0c0b..076ed556971 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -3767,6 +3767,29 @@ def test_connect() -> Literal[True]: assert raw_response_list == [True, True] +async def test_tcp_connector_setsockopts( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + """Check that sockopts get passed to socket""" + conn = aiohttp.TCPConnector( + tcp_sockopts=[(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2)] + ) + + with mock.patch.object( + conn._loop, "create_connection", autospec=True, spec_set=True + ) as create_connection: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + start_connection.return_value = s + create_connection.return_value = mock.Mock(), mock.Mock() + + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + + with closing(await conn.connect(req, [], ClientTimeout())): + assert s.getsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT) == 2 + + await conn.close() + + def test_default_ssl_context_creation_without_ssl() -> None: """Verify _make_ssl_context does not raise when ssl is not available.""" with mock.patch.object(connector_module, "ssl", None): From 17983d356a71e9609b81bee79ccb6abc7b2158e7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:58:42 +0000 Subject: [PATCH 32/39] [PR #10474/7379a866 backport][3.12] Expose setsockopt in TCPConnector API (#10486) **This is a backport of PR #10474 as merged into master (7379a866bb9fa41986a01aa6fff2a73a210b66de).** Co-authored-by: Tim Menninger --- CHANGES/10474.feature.rst | 2 ++ CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 12 ++++++++++++ docs/client_advanced.rst | 15 +++++++++++++++ docs/client_reference.rst | 9 ++++++++- tests/test_connector.py | 23 +++++++++++++++++++++++ 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10474.feature.rst diff --git a/CHANGES/10474.feature.rst b/CHANGES/10474.feature.rst new file mode 100644 index 00000000000..d5d6e4b40b9 --- /dev/null +++ b/CHANGES/10474.feature.rst @@ -0,0 +1,2 @@ +Added ``tcp_sockopts`` to ``TCPConnector`` to allow specifying custom socket options +-- by :user:`TimMenninger`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 9dd9d873003..fb5217e3e6b 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -332,6 +332,7 @@ Thanos Lefteris Thijs Vermeir Thomas Forbes Thomas Grainger +Tim Menninger Tolga Tezel Tomasz Trebski Toshiaki Tanaka diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 14433ba37e1..75d5796f7d2 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -19,6 +19,7 @@ DefaultDict, Deque, Dict, + Iterable, Iterator, List, Literal, @@ -60,6 +61,11 @@ ) from .resolver import DefaultResolver +if sys.version_info >= (3, 12): + from collections.abc import Buffer +else: + Buffer = Union[bytes, bytearray, "memoryview[int]", "memoryview[bytes]"] + if TYPE_CHECKING: import ssl @@ -828,6 +834,8 @@ class TCPConnector(BaseConnector): the happy eyeballs algorithm, set to None. interleave - “First Address Family Count” as defined in RFC 8305 loop - Optional event loop. + tcp_sockopts - List of tuples of sockopts applied to underlying + socket """ allowed_protocol_schema_set = HIGH_LEVEL_SCHEMA_SET | frozenset({"tcp"}) @@ -853,6 +861,7 @@ def __init__( timeout_ceil_threshold: float = 5, happy_eyeballs_delay: Optional[float] = 0.25, interleave: Optional[int] = None, + tcp_sockopts: Iterable[Tuple[int, int, Union[int, Buffer]]] = [], ): super().__init__( keepalive_timeout=keepalive_timeout, @@ -879,6 +888,7 @@ def __init__( self._happy_eyeballs_delay = happy_eyeballs_delay self._interleave = interleave self._resolve_host_tasks: Set["asyncio.Task[List[ResolveResult]]"] = set() + self._tcp_sockopts = tcp_sockopts def close(self) -> Awaitable[None]: """Close all ongoing DNS calls.""" @@ -1120,6 +1130,8 @@ async def _wrap_create_connection( interleave=self._interleave, loop=self._loop, ) + for sockopt in self._tcp_sockopts: + sock.setsockopt(*sockopt) connection = await self._loop.create_connection( *args, **kwargs, sock=sock ) diff --git a/docs/client_advanced.rst b/docs/client_advanced.rst index 2d00418ffac..eeb0ee98574 100644 --- a/docs/client_advanced.rst +++ b/docs/client_advanced.rst @@ -461,6 +461,21 @@ If your HTTP server uses UNIX domain sockets you can use session = aiohttp.ClientSession(connector=conn) +Setting socket options +^^^^^^^^^^^^^^^^^^^^^^ + +Socket options passed to the :class:`~aiohttp.TCPConnector` will be passed +to the underlying socket when creating a connection. For example, we may +want to change the conditions under which we consider a connection dead. +The following would change that to 9*7200 = 18 hours:: + + import socket + + conn = aiohttp.TCPConnector(tcp_sockopts=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True), + (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7200), + (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 9) ]) + + Named pipes in Windows ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/client_reference.rst b/docs/client_reference.rst index 013c43a13e4..1e49b014007 100644 --- a/docs/client_reference.rst +++ b/docs/client_reference.rst @@ -1144,7 +1144,8 @@ is controlled by *force_close* constructor's parameter). resolver=None, keepalive_timeout=sentinel, \ force_close=False, limit=100, limit_per_host=0, \ enable_cleanup_closed=False, timeout_ceil_threshold=5, \ - happy_eyeballs_delay=0.25, interleave=None, loop=None) + happy_eyeballs_delay=0.25, interleave=None, loop=None, \ + tcp_sockopts=[]) Connector for working with *HTTP* and *HTTPS* via *TCP* sockets. @@ -1265,6 +1266,12 @@ is controlled by *force_close* constructor's parameter). .. versionadded:: 3.10 + :param list tcp_sockopts: options applied to the socket when a connection is + created. This should be a list of 3-tuples, each a ``(level, optname, value)``. + Each tuple is deconstructed and passed verbatim to ``.setsockopt``. + + .. versionadded:: 3.12 + .. attribute:: family *TCP* socket family e.g. :data:`socket.AF_INET` or diff --git a/tests/test_connector.py b/tests/test_connector.py index e79b36a673d..b7531361287 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -3581,6 +3581,29 @@ def test_connect() -> Literal[True]: assert raw_response_list == [True, True] +async def test_tcp_connector_setsockopts( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + """Check that sockopts get passed to socket""" + conn = aiohttp.TCPConnector( + tcp_sockopts=[(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2)] + ) + + with mock.patch.object( + conn._loop, "create_connection", autospec=True, spec_set=True + ) as create_connection: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + start_connection.return_value = s + create_connection.return_value = mock.Mock(), mock.Mock() + + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + + with closing(await conn.connect(req, [], ClientTimeout())): + assert s.getsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT) == 2 + + await conn.close() + + def test_default_ssl_context_creation_without_ssl() -> None: """Verify _make_ssl_context does not raise when ssl is not available.""" with mock.patch.object(connector_module, "ssl", None): From ca6b798ac19fabbfca7d58c5c749369c757b588c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:07:35 +0000 Subject: [PATCH 33/39] Bump identify from 2.6.7 to 2.6.8 (#10487) Bumps [identify](https://github.com/pre-commit/identify) from 2.6.7 to 2.6.8.
Commits
  • f905a2e v2.6.8
  • 6d9a7b6 Merge pull request #511 from cidlik/main
  • 9f16bfa Merge pull request #510 from jodood/feature/sas
  • c100631 extensions: Introduce wsdl
  • 4de539a feat: Register sas as an extension
  • 3b17031 Merge pull request #509 from pre-commit/pre-commit-ci-update-config
  • 20eb272 [pre-commit.ci] pre-commit autoupdate
  • 9ae7182 Merge pull request #507 from pre-commit/pre-commit-ci-update-config
  • ce5c8d9 [pre-commit.ci] pre-commit autoupdate
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=identify&package-manager=pip&previous-version=2.6.7&new-version=2.6.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index eba33f77d34..10caf7ef5f2 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -86,7 +86,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.6 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index bd503228bb0..9138c7efb44 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -84,7 +84,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.6 # via diff --git a/requirements/lint.txt b/requirements/lint.txt index 039698a23cc..19af47914ff 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -33,7 +33,7 @@ forbiddenfruit==0.1.4 # via blockbuster freezegun==1.5.1 # via -r requirements/lint.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.7 # via trustme From d64535a030ff2fc304b20cc6b5b20b49900da2af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:18:15 +0000 Subject: [PATCH 34/39] Bump blockbuster from 1.5.22 to 1.5.23 (#10488) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps [blockbuster](https://github.com/cbornet/blockbuster) from 1.5.22 to 1.5.23.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=blockbuster&package-manager=pip&previous-version=1.5.22&new-version=1.5.23)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- requirements/test.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 10caf7ef5f2..c3cd82086cd 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # valkey babel==2.17.0 # via sphinx -blockbuster==1.5.22 +blockbuster==1.5.23 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 9138c7efb44..d1ab256f3e5 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # valkey babel==2.17.0 # via sphinx -blockbuster==1.5.22 +blockbuster==1.5.23 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/lint.txt b/requirements/lint.txt index 19af47914ff..c186db8ac84 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -10,7 +10,7 @@ annotated-types==0.7.0 # via pydantic async-timeout==5.0.1 # via valkey -blockbuster==1.5.22 +blockbuster==1.5.23 # via -r requirements/lint.in cffi==1.17.1 # via diff --git a/requirements/test.txt b/requirements/test.txt index b5a04884fd8..b728abf4ee3 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -14,7 +14,7 @@ annotated-types==0.7.0 # via pydantic async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in -blockbuster==1.5.22 +blockbuster==1.5.23 # via -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in From c8143c317c9403f4a5f58cd17056508c756c26a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:28:21 +0000 Subject: [PATCH 35/39] Bump identify from 2.6.7 to 2.6.8 (#10489) Bumps [identify](https://github.com/pre-commit/identify) from 2.6.7 to 2.6.8.
Commits
  • f905a2e v2.6.8
  • 6d9a7b6 Merge pull request #511 from cidlik/main
  • 9f16bfa Merge pull request #510 from jodood/feature/sas
  • c100631 extensions: Introduce wsdl
  • 4de539a feat: Register sas as an extension
  • 3b17031 Merge pull request #509 from pre-commit/pre-commit-ci-update-config
  • 20eb272 [pre-commit.ci] pre-commit autoupdate
  • 9ae7182 Merge pull request #507 from pre-commit/pre-commit-ci-update-config
  • ce5c8d9 [pre-commit.ci] pre-commit autoupdate
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=identify&package-manager=pip&previous-version=2.6.7&new-version=2.6.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index adfdd34ce8d..acac48ef15f 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -88,7 +88,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.3 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index 3d536fc0a41..0ea100e733e 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -86,7 +86,7 @@ gidgethub==5.3.0 # via cherry-picker gunicorn==23.0.0 # via -r requirements/base.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.4 # via diff --git a/requirements/lint.txt b/requirements/lint.txt index a8195a21d4b..ff0677c855a 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -33,7 +33,7 @@ forbiddenfruit==0.1.4 # via blockbuster freezegun==1.5.1 # via -r requirements/lint.in -identify==2.6.7 +identify==2.6.8 # via pre-commit idna==3.7 # via trustme From 94924a32f6e69cabeaff142167458a6c4cd63e90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:36:33 +0000 Subject: [PATCH 36/39] Bump blockbuster from 1.5.22 to 1.5.23 (#10490) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps [blockbuster](https://github.com/cbornet/blockbuster) from 1.5.22 to 1.5.23.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=blockbuster&package-manager=pip&previous-version=1.5.22&new-version=1.5.23)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/lint.txt | 2 +- requirements/test.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index acac48ef15f..591d7b5af31 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -26,7 +26,7 @@ attrs==25.1.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx -blockbuster==1.5.22 +blockbuster==1.5.23 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index 0ea100e733e..78e0fdec604 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -26,7 +26,7 @@ attrs==25.1.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx -blockbuster==1.5.22 +blockbuster==1.5.23 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/lint.txt b/requirements/lint.txt index ff0677c855a..26b62bff3fc 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -10,7 +10,7 @@ annotated-types==0.7.0 # via pydantic async-timeout==5.0.1 # via valkey -blockbuster==1.5.22 +blockbuster==1.5.23 # via -r requirements/lint.in cffi==1.17.1 # via diff --git a/requirements/test.txt b/requirements/test.txt index 2a71315b0f7..a4f30c80b76 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -16,7 +16,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in attrs==25.1.0 # via -r requirements/runtime-deps.in -blockbuster==1.5.22 +blockbuster==1.5.23 # via -r requirements/test.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in From 6f09c515993ce754f009428df55b28bb77d202a6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 24 Feb 2025 10:04:30 -0500 Subject: [PATCH 37/39] Release 3.11.13 (#10491) --- CHANGES.rst | 53 +++++++++++++++++++++++++++++++++++++ CHANGES/10422.misc.rst | 3 --- CHANGES/10423.packaging.rst | 1 - CHANGES/10434.bugfix.rst | 2 -- CHANGES/10464.bugfix.rst | 1 - aiohttp/__init__.py | 2 +- 6 files changed, 54 insertions(+), 8 deletions(-) delete mode 100644 CHANGES/10422.misc.rst delete mode 100644 CHANGES/10423.packaging.rst delete mode 100644 CHANGES/10434.bugfix.rst delete mode 100644 CHANGES/10464.bugfix.rst diff --git a/CHANGES.rst b/CHANGES.rst index 104dd7a746d..39c45196c26 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,59 @@ .. towncrier release notes start +3.11.13 (2025-02-24) +==================== + +Bug fixes +--------- + +- Removed a break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler` + -- by :user:`Cycloctane`. + + + *Related issues and pull requests on GitHub:* + :issue:`10434`. + + + +- Changed connection creation to explicitly close sockets if an exception is raised in the event loop's ``create_connection`` method -- by :user:`top-oai`. + + + *Related issues and pull requests on GitHub:* + :issue:`10464`. + + + + +Packaging updates and notes for downstreams +------------------------------------------- + +- Fixed test ``test_write_large_payload_deflate_compression_data_in_eof_writelines`` failing with Python 3.12.9+ or 3.13.2+ -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`10423`. + + + + +Miscellaneous internal changes +------------------------------ + +- Added human-readable error messages to the exceptions for WebSocket disconnects due to PONG not being received -- by :user:`bdraco`. + + Previously, the error messages were empty strings, which made it hard to determine what went wrong. + + + *Related issues and pull requests on GitHub:* + :issue:`10422`. + + + + +---- + + 3.11.12 (2025-02-05) ==================== diff --git a/CHANGES/10422.misc.rst b/CHANGES/10422.misc.rst deleted file mode 100644 index 7ecb1c0e2e2..00000000000 --- a/CHANGES/10422.misc.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added human-readable error messages to the exceptions for WebSocket disconnects due to PONG not being received -- by :user:`bdraco`. - -Previously, the error messages were empty strings, which made it hard to determine what went wrong. diff --git a/CHANGES/10423.packaging.rst b/CHANGES/10423.packaging.rst deleted file mode 100644 index 6cf58c5a10b..00000000000 --- a/CHANGES/10423.packaging.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed test ``test_write_large_payload_deflate_compression_data_in_eof_writelines`` failing with Python 3.12.9+ or 3.13.2+ -- by :user:`bdraco`. diff --git a/CHANGES/10434.bugfix.rst b/CHANGES/10434.bugfix.rst deleted file mode 100644 index c4bc50dc6aa..00000000000 --- a/CHANGES/10434.bugfix.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler` --- by :user:`Cycloctane`. diff --git a/CHANGES/10464.bugfix.rst b/CHANGES/10464.bugfix.rst deleted file mode 100644 index 4e21000a317..00000000000 --- a/CHANGES/10464.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Changed connection creation to explicitly close sockets if an exception is raised in the event loop's ``create_connection`` method -- by :user:`top-oai`. diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 6652a0b979d..786eed63650 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.11.13.dev0" +__version__ = "3.11.13" from typing import TYPE_CHECKING, Tuple From 8e8fa959e811f95c73bf09966f534e5abf3c452e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 26 Feb 2025 03:31:45 +0000 Subject: [PATCH 38/39] Document adjustments to the release process (#10493) --- docs/contributing-admins.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/contributing-admins.rst b/docs/contributing-admins.rst index acfaebc0e97..b17cbe1019a 100644 --- a/docs/contributing-admins.rst +++ b/docs/contributing-admins.rst @@ -21,9 +21,9 @@ To create a new release: #. Run ``towncrier``. #. Check and cleanup the changes in ``CHANGES.rst``. #. Checkout a new branch: e.g. ``git checkout -b release/v3.8.6`` -#. Commit and create a PR. Once PR is merged, continue. +#. Commit and create a PR. Verify the changelog and release notes look good on Read the Docs. Once PR is merged, continue. #. Go back to the release branch: e.g. ``git checkout 3.8 && git pull`` -#. Add a tag: e.g. ``git tag -a v3.8.6 -m 'Release 3.8.6'`` +#. Add a tag: e.g. ``git tag -a v3.8.6 -m 'Release 3.8.6' -s`` #. Push the tag: e.g. ``git push origin v3.8.6`` #. Monitor CI to ensure release process completes without errors. @@ -49,6 +49,10 @@ first merge into the newer release branch (e.g. 3.8 into 3.9) and then to master Back on the original release branch, bump the version number and append ``.dev0`` in ``__init__.py``. +Post the release announcement to social media: + - BlueSky: https://bsky.app/profile/aiohttp.org and re-post to https://bsky.app/profile/aio-libs.org + - Mastodon: https://fosstodon.org/@aiohttp and re-post to https://fosstodon.org/@aio_libs + If doing a minor release: #. Create a new release branch for future features to go to: e.g. ``git checkout -b 3.10 3.9 && git push`` From c738a83d5ad0c270df94b8f93a206f0c348896e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 10:28:59 +0000 Subject: [PATCH 39/39] Bump setuptools from 75.8.0 to 75.8.1 (#10497) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [setuptools](https://github.com/pypa/setuptools) from 75.8.0 to 75.8.1.
Changelog

Sourced from setuptools's changelog.

v75.8.1

Bugfixes

  • Fix wheel file naming to follow binary distribution specification -- by :user:di (#4766)
  • Fixed crash generating error message printed when building wheels for the free-threaded build using the limited API. -- by :user:ngoldbaum (#4809)
  • Fix documentation for recent CFLAGS distutils change. -- by :user:thesamesam (#4836)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=setuptools&package-manager=pip&previous-version=75.8.0&new-version=75.8.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/constraints.txt | 2 +- requirements/dev.txt | 2 +- requirements/doc-spelling.txt | 2 +- requirements/doc.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index c3cd82086cd..9e05c4e7624 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -284,7 +284,7 @@ yarl==1.18.3 # The following packages are considered to be unsafe in a requirements file: pip==25.0.1 # via pip-tools -setuptools==75.8.0 +setuptools==75.8.1 # via # incremental # pip-tools diff --git a/requirements/dev.txt b/requirements/dev.txt index d1ab256f3e5..82b9e83e647 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -275,7 +275,7 @@ yarl==1.18.3 # The following packages are considered to be unsafe in a requirements file: pip==25.0.1 # via pip-tools -setuptools==75.8.0 +setuptools==75.8.1 # via # incremental # pip-tools diff --git a/requirements/doc-spelling.txt b/requirements/doc-spelling.txt index c22df39a396..055e18cd48f 100644 --- a/requirements/doc-spelling.txt +++ b/requirements/doc-spelling.txt @@ -76,5 +76,5 @@ urllib3==2.3.0 # via requests # The following packages are considered to be unsafe in a requirements file: -setuptools==75.8.0 +setuptools==75.8.1 # via incremental diff --git a/requirements/doc.txt b/requirements/doc.txt index 491eb3453de..8626f5f1b67 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -69,5 +69,5 @@ urllib3==2.3.0 # via requests # The following packages are considered to be unsafe in a requirements file: -setuptools==75.8.0 +setuptools==75.8.1 # via incremental