From 613a3f0a13ef2b7fd567c09651ac344e3fd50e08 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 24 Feb 2025 16:25:50 +0000 Subject: [PATCH 01/43] Increment version to 3.11.14.dev0 --- aiohttp/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 786eed63650..96eced5960d 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.11.13" +__version__ = "3.11.14.dev0" from typing import TYPE_CHECKING, Tuple From f4cdb6e347a5e3da9f3ccc0c7b4d0f4d29c66186 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:21:14 +0100 Subject: [PATCH 02/43] [PR #10493/8e8fa959 backport][3.12] Document adjustments to the release process (#10496) **This is a backport of PR #10493 as merged into master (8e8fa959e811f95c73bf09966f534e5abf3c452e).** - Adding some notes here so I do not forget the social media posting - Add note to check RTD to verify the changelog looks good - Sign the tags Co-authored-by: J. Nick Koston --- 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 40fe535ca81be698eafa6f43f9ae2cb19016b795 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:21:37 +0100 Subject: [PATCH 03/43] [PR #10493/8e8fa959 backport][3.11] Document adjustments to the release process (#10495) **This is a backport of PR #10493 as merged into master (8e8fa959e811f95c73bf09966f534e5abf3c452e).** - Adding some notes here so I do not forget the social media posting - Add note to check RTD to verify the changelog looks good - Sign the tags Co-authored-by: J. Nick Koston --- 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 6ede5e021d755eef5b7bb1575252375a57d2a75c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:02:19 +0000 Subject: [PATCH 04/43] Bump setuptools from 75.8.0 to 75.8.1 (#10498) 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 591d7b5af31..69a93b02ce3 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -288,7 +288,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 78e0fdec604..cb00e041889 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -279,7 +279,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 4be7358fe8d..a5408f08014 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 8324f007e3a..a69dbe4b14d 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 From 470ae18ab89799a57681e0c5c12d186dcb7411b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:38:28 +0000 Subject: [PATCH 05/43] Bump setuptools from 75.8.1 to 75.8.2 (#10499) 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.1 to 75.8.2.
Changelog

Sourced from setuptools's changelog.

v75.8.2

Bugfixes

  • Fixed pkg_resources.require(...) to also consider standardised dist-info directories. (#4856)
Commits
  • 9aa3771 Bump version: 75.8.1 → 75.8.2
  • c0f39c0 Update WorkingSet.find to consider standardised .dist-info directory names (#...
  • edca181 Add news fragment
  • 22355fc Also consider '-' separator in tests
  • 8280e2c Attempt to solve path normalisation issue in windows tests
  • a3718c8 Slightly change test, so that we are sure about the correct distribution bein...
  • 23b73aa Fix mypy errors
  • 2c24223 Update WorkingSet.find to consider standardised dist-info names
  • 79d6e46 Add regression test for issue 4853
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=setuptools&package-manager=pip&previous-version=75.8.1&new-version=75.8.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/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 69a93b02ce3..265115d0b1f 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -288,7 +288,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.1 +setuptools==75.8.2 # via # incremental # pip-tools diff --git a/requirements/dev.txt b/requirements/dev.txt index cb00e041889..2cb8d351b72 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -279,7 +279,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.1 +setuptools==75.8.2 # via # incremental # pip-tools diff --git a/requirements/doc-spelling.txt b/requirements/doc-spelling.txt index a5408f08014..687b6827211 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.1 +setuptools==75.8.2 # via incremental diff --git a/requirements/doc.txt b/requirements/doc.txt index a69dbe4b14d..ab132b5678e 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.1 +setuptools==75.8.2 # via incremental From f1a4d2eec84257981cf7e9e3e4ab094aabc561cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:41:50 +0000 Subject: [PATCH 06/43] Bump actions/cache from 4.2.1 to 4.2.2 (#10503) 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.1 to 4.2.2.
Release notes

Sourced from actions/cache's releases.

v4.2.2

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.

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

Changelog

Sourced from actions/cache's changelog.

4.2.2

  • Bump @actions/cache to v4.0.2
Commits
  • d4323d4 Merge pull request #1560 from actions/robherley/v4.2.2
  • da26677 bump @​actions/cache to v4.0.2, prep for v4.2.2 release
  • 7921ae2 Merge pull request #1557 from actions/robherley/ia-workflow-released
  • 3937731 Update publish-immutable-actions.yml
  • 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.1&new-version=4.2.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> --- .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 95f9fc7c631..a4f6d03c806 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.1 + uses: actions/cache@v4.2.2 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.1 + uses: actions/cache@v4.2.2 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.1 + uses: actions/cache@v4.2.2 with: key: pip-ci-${{ runner.os }}-${{ matrix.pyver }}-${{ matrix.no-extensions }}-${{ hashFiles('requirements/*.txt') }} path: ${{ steps.pip-cache.outputs.dir }} From 5124966aab34cf28ff0a9e5adbd976327323673c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:57:42 +0000 Subject: [PATCH 07/43] Bump sphinxcontrib-towncrier from 0.4.0a0 to 0.5.0a0 (#10504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [sphinxcontrib-towncrier](https://github.com/sphinx-contrib/sphinxcontrib-towncrier) from 0.4.0a0 to 0.5.0a0.
Release notes

Sourced from sphinxcontrib-towncrier's releases.

v0.5.0a0

Release v0.5.0a0

This release is published to https://pypi.org/project/sphinxcontrib-towncrier/0.5.0a0.

This release has been produced by the following workflow run: https://github.com/sphinx-contrib/sphinxcontrib-towncrier/actions/runs/13579622041.

🐛 What's Fixed

The main improvement is that @​bennyrowland💰 added support for Towncrier 24.7.0rc1 and higher via #96. Towncrier versions of year 2024 are now integrated into the CI as well (#93).

There are a few more corner case adjustments and fixes that we didn't bother recording as they aren't met in the “happy path”. They handle missing configs, files and directories.

🛠️ Internal Updates

@​dvzrv💰 upgraded setuptools-scm in packaging to rely on modern handling of git archives in #80

@​webknjaz💰 heavily refactored the CI/CD, introducing a reusable workflow generalizing tox invocations @ sphinx-contrib/sphinxcontrib-towncrier#106 and a few direct commits.

As a part of the testing improvements, the code coverage level has been raised to about 20% higher than before. Additionally, a typing has been fixed here and there.

☣️ Anything else I might care about?

[!caution] This release heavily reduced the support matrix. The minimum supported Python version is now 3.9. And the lowest required Towncrier is 23.

💪 New Contributors

🪞 Full Diff: https://github.com/sphinx-contrib/sphinxcontrib-towncrier/compare/v0.4.0a0...v0.5.0a0

🧔‍♂️ Release Manager: @​webknjaz 🇺🇦

🙏 Special Thanks to @​bennyrowland💰 for driving the Towncrier compatibility research and proposing fixes! They laid the foundation for this entire release.

💬 Discuss on Bluesky 🦋, on Mastodon 🐘 and on GitHub.

GH Sponsors badge

Commits
  • 8f76a55 🧪 Skip running pylint @ pre-commit.ci
  • 7014328 🧪 Bump Towncrier to v24 @ pre-commit
  • 28c6db9 [pre-commit.ci] pre-commit autoupdate (#105)
  • 20c1667 Bump jinja2 from 3.1.4 to 3.1.5 in /docs (#104)
  • 13b228c Merge branch 'maintenance/tox4-win'
  • ac01059 🚑 Force UTF-8 mode in CPython calling tox
  • a93edfe 🧪📦 Sync expected dist basename computation
  • 7b6a89a 🧪 Move cron runs into a separate GHA workflow
  • 7bda7ee Merge branch 'maintenance/gha-reusable-tox'
  • 26c1d04 [pre-commit.ci] pre-commit autoupdate
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=sphinxcontrib-towncrier&package-manager=pip&previous-version=0.4.0a0&new-version=0.5.0a0)](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 265115d0b1f..e1081b455f1 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -232,7 +232,7 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-spelling==8.0.1 ; platform_system != "Windows" # via -r requirements/doc-spelling.in -sphinxcontrib-towncrier==0.4.0a0 +sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in stamina==24.3.0 # via cherry-picker diff --git a/requirements/dev.txt b/requirements/dev.txt index 2cb8d351b72..d294cc0203e 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -223,7 +223,7 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sphinxcontrib-towncrier==0.4.0a0 +sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in stamina==24.3.0 # via cherry-picker diff --git a/requirements/doc-spelling.txt b/requirements/doc-spelling.txt index 687b6827211..48b8d4bce60 100644 --- a/requirements/doc-spelling.txt +++ b/requirements/doc-spelling.txt @@ -61,7 +61,7 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-spelling==8.0.1 ; platform_system != "Windows" # via -r requirements/doc-spelling.in -sphinxcontrib-towncrier==0.4.0a0 +sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in tomli==2.2.1 # via diff --git a/requirements/doc.txt b/requirements/doc.txt index ab132b5678e..b2fce4162ca 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -54,7 +54,7 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sphinxcontrib-towncrier==0.4.0a0 +sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in tomli==2.2.1 # via From f5d41407765c76c6e06675b7f0cedef5d14e2b20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:27:21 -1000 Subject: [PATCH 08/43] Bump pypa/cibuildwheel from 2.22.0 to 2.23.0 (#10511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 2.22.0 to 2.23.0.
Release notes

Sourced from pypa/cibuildwheel's releases.

v2.23.0

  • ✨ Adds official support for the new GitHub Actions Arm runners. In fact these worked out-of-the-box, now we include them in our tests and example configs. (#2135 via #2281)
  • ✨ Adds support for building PyPy 3.11 wheels (#2268 via #2281)
  • 🛠 Adopts the beta pypa/manylinux image for armv7l builds (#2269 via #2281)
  • 🛠 Dependency updates, including Pyodide 0.27 (#2117 and #2281)
Changelog

Sourced from pypa/cibuildwheel's changelog.

v2.23.0

1 March 2025

  • ✨ Adds official support for the new GitHub Actions Arm runners. In fact these worked out-of-the-box, now we include them in our tests and example configs. (#2135 via #2281)
  • ✨ Adds support for building PyPy 3.11 wheels (#2268 via #2281)
  • 🛠 Adopts the beta pypa/manylinux image for armv7l builds (#2269 via #2281)
  • 🛠 Dependency updates, including Pyodide 0.27 (#2117 and #2281)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pypa/cibuildwheel&package-manager=github_actions&previous-version=2.22.0&new-version=2.23.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> --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a4f6d03c806..cade6835b92 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -414,7 +414,7 @@ jobs: run: | make cythonize - name: Build wheels - uses: pypa/cibuildwheel@v2.22.0 + uses: pypa/cibuildwheel@v2.23.0 env: CIBW_SKIP: pp* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }} CIBW_ARCHS_MACOS: x86_64 arm64 universal2 From 29ca84306e3ef658721a2d88b8a0b6dc07a87cd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:27:36 -1000 Subject: [PATCH 09/43] Bump pytest from 8.3.4 to 8.3.5 (#10510) Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.4 to 8.3.5.
Release notes

Sourced from pytest's releases.

8.3.5

pytest 8.3.5 (2025-03-02)

Bug fixes

  • #11777: Fixed issue where sequences were still being shortened even with -vv verbosity.
  • #12888: Fixed broken input when using Python 3.13+ and a libedit build of Python, such as on macOS or with uv-managed Python binaries from the python-build-standalone project. This could manifest e.g. by a broken prompt when using Pdb, or seeing empty inputs with manual usage of input() and suspended capturing.
  • #13026: Fixed AttributeError{.interpreted-text role="class"} crash when using --import-mode=importlib when top-level directory same name as another module of the standard library.
  • #13053: Fixed a regression in pytest 8.3.4 where, when using --import-mode=importlib, a directory containing py file with the same name would cause an ImportError
  • #13083: Fixed issue where pytest could crash if one of the collected directories got removed during collection.

Improved documentation

  • #12842: Added dedicated page about using types with pytest.

    See types{.interpreted-text role="ref"} for detailed usage.

Contributor-facing changes

  • #13112: Fixed selftest failures in test_terminal.py with Pygments >= 2.19.0
  • #13256: Support for Towncrier versions released in 2024 has been re-enabled when building Sphinx docs -- by webknjaz{.interpreted-text role="user"}.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pytest&package-manager=pip&previous-version=8.3.4&new-version=8.3.5)](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 e1081b455f1..3f5589421be 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -166,7 +166,7 @@ pyproject-hooks==1.2.0 # via # build # pip-tools -pytest==8.3.4 +pytest==8.3.5 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/dev.txt b/requirements/dev.txt index d294cc0203e..0e329c562ec 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -161,7 +161,7 @@ pyproject-hooks==1.2.0 # via # build # pip-tools -pytest==8.3.4 +pytest==8.3.5 # via # -r requirements/lint.in # -r requirements/test.in diff --git a/requirements/lint.txt b/requirements/lint.txt index 26b62bff3fc..ceb4fce019d 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -67,7 +67,7 @@ pydantic-core==2.27.2 # via pydantic pygments==2.19.1 # via rich -pytest==8.3.4 +pytest==8.3.5 # via # -r requirements/lint.in # pytest-codspeed diff --git a/requirements/test.txt b/requirements/test.txt index a4f30c80b76..3fcfcbcb869 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -87,7 +87,7 @@ pydantic-core==2.27.2 # via pydantic pygments==2.19.1 # via rich -pytest==8.3.4 +pytest==8.3.5 # via # -r requirements/test.in # pytest-codspeed From 9ccca2585e8447344a47430aaa1bb98baadcee74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:27:54 -1000 Subject: [PATCH 10/43] Bump cryptography from 44.0.1 to 44.0.2 (#10509) Bumps [cryptography](https://github.com/pyca/cryptography) from 44.0.1 to 44.0.2.
Changelog

Sourced from cryptography's changelog.

44.0.2 - 2025-03-01


* We now build wheels for PyPy 3.11.

.. _v44-0-1:

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cryptography&package-manager=pip&previous-version=44.0.1&new-version=44.0.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 +- requirements/test.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 3f5589421be..dae27da7eda 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -58,7 +58,7 @@ coverage==7.6.12 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.1 +cryptography==44.0.2 # via # pyjwt # trustme diff --git a/requirements/dev.txt b/requirements/dev.txt index 0e329c562ec..594302de133 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -58,7 +58,7 @@ coverage==7.6.12 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.1 +cryptography==44.0.2 # via # pyjwt # trustme diff --git a/requirements/lint.txt b/requirements/lint.txt index ceb4fce019d..5740ddb58a0 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -21,7 +21,7 @@ cfgv==3.4.0 # via pre-commit click==8.1.8 # via slotscheck -cryptography==44.0.1 +cryptography==44.0.2 # via trustme distlib==0.3.9 # via virtualenv diff --git a/requirements/test.txt b/requirements/test.txt index 3fcfcbcb869..9b35aab8cb7 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -31,7 +31,7 @@ coverage==7.6.12 # via # -r requirements/test.in # pytest-cov -cryptography==44.0.1 +cryptography==44.0.2 # via trustme exceptiongroup==1.2.2 # via pytest From bc3e5cdb5abfd1043af9e12517fd55221f6a01cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 05:52:30 -1000 Subject: [PATCH 11/43] Bump aiohappyeyeballs from 2.4.6 to 2.4.8 (#10517) Bumps [aiohappyeyeballs](https://github.com/aio-libs/aiohappyeyeballs) from 2.4.6 to 2.4.8.
Release notes

Sourced from aiohappyeyeballs's releases.

v2.4.8 (2025-03-04)

Bug Fixes

  • Close runner up sockets in the event there are multiple winners (#143, 476a05b)

The first attempt to fix this was to use the cpython staggered race updates in #142 but there is still a race there where there can be multiple winners. Instead we now accept that we will not be able to cancel all coros in time and there will always be a risk of multiple winners. We store all sockets in a set that were not already cleaned up and we close all but the first winner after the staggered race finishes.


Detailed Changes: v2.4.7...v2.4.8

v2.4.7 (2025-03-04)

Bug Fixes

  • Resolve warnings when running tests (#144, e96264a)

  • Instead of raising SystemExit which causes a RuntimeError, mock out SystemExit to a new exception

  • Make sure the event loop is closed in tests

fixes #97


Detailed Changes: v2.4.6...v2.4.7

Changelog

Sourced from aiohappyeyeballs's changelog.

v2.4.8 (2025-03-04)

Bug fixes

  • Close runner up sockets in the event there are multiple winners (#143) (476a05b)

v2.4.7 (2025-03-04)

Bug fixes

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohappyeyeballs&package-manager=pip&previous-version=2.4.6&new-version=2.4.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/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 fb7a1d43f43..f56b3bda93c 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.6 +aiohappyeyeballs==2.4.8 # 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 dae27da7eda..38b472dc453 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.6 +aiohappyeyeballs==2.4.8 # 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 594302de133..2ab4fb7bb57 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.6 +aiohappyeyeballs==2.4.8 # 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 4265eab71a3..cb9deee6bd2 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.6 +aiohappyeyeballs==2.4.8 # 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 9b35aab8cb7..4b3daedf2c8 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.6 +aiohappyeyeballs==2.4.8 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in From 76a9dc692e08ec38e6f15107165d44b1d792ab49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:09:15 +0000 Subject: [PATCH 12/43] Bump aiohappyeyeballs from 2.4.8 to 2.5.0 (#10523) Bumps [aiohappyeyeballs](https://github.com/aio-libs/aiohappyeyeballs) from 2.4.8 to 2.5.0.
Release notes

Sourced from aiohappyeyeballs's releases.

v2.5.0 (2025-03-06)

Features

  • Add callback for users to customize socket creation (#147, 8e1bc6a)

Co-authored-by: Kieren


Detailed Changes: v2.4.8...v2.5.0

Changelog

Sourced from aiohappyeyeballs's changelog.

v2.5.0 (2025-03-06)

Features

  • Add callback for users to customize socket creation (#147) (8e1bc6a)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohappyeyeballs&package-manager=pip&previous-version=2.4.8&new-version=2.5.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 f56b3bda93c..de111dd8268 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.8 +aiohappyeyeballs==2.5.0 # 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 38b472dc453..57c94399c91 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.8 +aiohappyeyeballs==2.5.0 # 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 2ab4fb7bb57..e490f947f44 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.8 +aiohappyeyeballs==2.5.0 # 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 cb9deee6bd2..128b0ed2d6f 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.8 +aiohappyeyeballs==2.5.0 # 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 4b3daedf2c8..ea0451e9ea6 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.8 +aiohappyeyeballs==2.5.0 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in From 2761ce82a031c3d4fb8ff9896175f38960051702 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:34:05 +0000 Subject: [PATCH 13/43] Bump jinja2 from 3.1.5 to 3.1.6 (#10522) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.5 to 3.1.6.
Release notes

Sourced from jinja2's releases.

3.1.6

This is the Jinja 3.1.6 security release, which fixes security issues but does not otherwise change behavior and should not result in breaking changes compared to the latest feature release.

PyPI: https://pypi.org/project/Jinja2/3.1.6/ Changes: https://jinja.palletsprojects.com/en/stable/changes/#version-3-1-6

Changelog

Sourced from jinja2's changelog.

Version 3.1.6

Released 2025-03-05

  • The |attr filter does not bypass the environment's attribute lookup, allowing the sandbox to apply its checks. :ghsa:cpwx-vrp4-4pq7
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jinja2&package-manager=pip&previous-version=3.1.5&new-version=3.1.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/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 57c94399c91..ccfb8ea989e 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -101,7 +101,7 @@ incremental==24.7.2 # via towncrier iniconfig==2.0.0 # via pytest -jinja2==3.1.5 +jinja2==3.1.6 # via # sphinx # towncrier diff --git a/requirements/dev.txt b/requirements/dev.txt index e490f947f44..bb0e6b6bba2 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -99,7 +99,7 @@ incremental==24.7.2 # via towncrier iniconfig==2.0.0 # via pytest -jinja2==3.1.5 +jinja2==3.1.6 # via # sphinx # towncrier diff --git a/requirements/doc-spelling.txt b/requirements/doc-spelling.txt index 48b8d4bce60..07c0c6b8b1c 100644 --- a/requirements/doc-spelling.txt +++ b/requirements/doc-spelling.txt @@ -24,7 +24,7 @@ imagesize==1.4.1 # via sphinx incremental==24.7.2 # via towncrier -jinja2==3.1.5 +jinja2==3.1.6 # via # sphinx # towncrier diff --git a/requirements/doc.txt b/requirements/doc.txt index b2fce4162ca..74e0ebfcda7 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -24,7 +24,7 @@ imagesize==1.4.1 # via sphinx incremental==24.7.2 # via towncrier -jinja2==3.1.5 +jinja2==3.1.6 # via # sphinx # towncrier From 505d307e98d1b970fd16696aced4a968f8e9e49d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 10:52:37 +0000 Subject: [PATCH 14/43] Bump virtualenv from 20.29.2 to 20.29.3 (#10527) Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.29.2 to 20.29.3.
Changelog

Sourced from virtualenv's changelog.

v20.29.3 (2025-03-06)

Bugfixes - 20.29.3

- Ignore unreadable directories in ``PATH``. (:issue:`2794`)
Commits
  • b1666e9 release 20.29.3
  • e05b286 Merge pull request #2853 from pypa/pre-commit-ci-update-config
  • d6bc4a9 [pre-commit.ci] pre-commit autoupdate
  • 1fc647e Merge pull request #2852 from barneygale/fix-2794
  • 4567521 Add changelog entry
  • 220b6b8 Add test
  • ee9d84c Ignore directories in PATH that can't be opened (#2794)
  • 7365ad2 Merge pull request #2849 from tipabu/logging-interpolation
  • 5b74c9a Merge pull request #2850 from shenxianpeng/remove-duplicate-template
  • ca5935a Remove duplicate bug report template
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=virtualenv&package-manager=pip&previous-version=20.29.2&new-version=20.29.3)](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 ccfb8ea989e..7a00dcae42f 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -276,7 +276,7 @@ uvloop==0.21.0 ; platform_system != "Windows" # -r requirements/lint.in valkey==6.1.0 # via -r requirements/lint.in -virtualenv==20.29.2 +virtualenv==20.29.3 # 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 bb0e6b6bba2..281c2c0a08b 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -267,7 +267,7 @@ uvloop==0.21.0 ; platform_system != "Windows" and implementation_name == "cpytho # -r requirements/lint.in valkey==6.1.0 # via -r requirements/lint.in -virtualenv==20.29.2 +virtualenv==20.29.3 # 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 5740ddb58a0..d2dba87daf8 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -106,5 +106,5 @@ uvloop==0.21.0 ; platform_system != "Windows" # via -r requirements/lint.in valkey==6.1.0 # via -r requirements/lint.in -virtualenv==20.29.2 +virtualenv==20.29.3 # via pre-commit From e1ef02d2058cb9bcc55c79b970216503f16dbbe8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:11:32 +0000 Subject: [PATCH 15/43] Bump setuptools from 75.8.2 to 76.0.0 (#10530) 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.2 to 76.0.0.
Changelog

Sourced from setuptools's changelog.

v76.0.0

Deprecations and Removals

  • Synced with pypa/distutils@5589d7527 including a simplified shebang generation when building scripts (#4863). (#4865)

v75.9.1

Bugfixes

  • Fix ImportError in distutils when configuring for linking. (#4866)

v75.9.0

Features

  • pypa/distutils#327#4852)
Commits
  • c11a494 Bump version: 75.9.1 → 76.0.0
  • 427babb Merge pull request #4865 from pypa/feature/distutils-5589d7527
  • 7530d69 Bump version: 75.9.0 → 75.9.1
  • d8620a8 Merge pull request #4867 from pypa/bugfix/distutils-6d7cc0ff9
  • 7cff740 Add news fragment.
  • 149a28a Merge commit '6d7cc0ff9' into bugfix/distutils-6d7cc0ff9
  • 6d7cc0f In config command, move to eager imports. Restore LinkError to ccompilers mod...
  • 5cc2927 Add news fragment.
  • c7e97a0 Merge with pypa/distutils@5589d7527
  • 0cffd61 Bump version: 75.8.2 → 75.9.0
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=setuptools&package-manager=pip&previous-version=75.8.2&new-version=76.0.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/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 7a00dcae42f..0a6748b9704 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -288,7 +288,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.2 +setuptools==76.0.0 # via # incremental # pip-tools diff --git a/requirements/dev.txt b/requirements/dev.txt index 281c2c0a08b..998cc2fdee5 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -279,7 +279,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.2 +setuptools==76.0.0 # via # incremental # pip-tools diff --git a/requirements/doc-spelling.txt b/requirements/doc-spelling.txt index 07c0c6b8b1c..ff527ae486b 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.2 +setuptools==76.0.0 # via incremental diff --git a/requirements/doc.txt b/requirements/doc.txt index 74e0ebfcda7..f00d523f092 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.2 +setuptools==76.0.0 # via incremental From 98804dcb6e92d10abbfe1e95c2301b19031d9df6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:21:39 +0000 Subject: [PATCH 16/43] Bump identify from 2.6.8 to 2.6.9 (#10531) Bumps [identify](https://github.com/pre-commit/identify) from 2.6.8 to 2.6.9.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=identify&package-manager=pip&previous-version=2.6.8&new-version=2.6.9)](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 0a6748b9704..184642b29bb 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.8 +identify==2.6.9 # via pre-commit idna==3.3 # via diff --git a/requirements/dev.txt b/requirements/dev.txt index 998cc2fdee5..30afd855beb 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.8 +identify==2.6.9 # via pre-commit idna==3.4 # via diff --git a/requirements/lint.txt b/requirements/lint.txt index d2dba87daf8..d25a756f73e 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.8 +identify==2.6.9 # via pre-commit idna==3.7 # via trustme From c1fdd1af0aa03d9c73ba104256706ea477abfeb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 10:52:35 +0000 Subject: [PATCH 17/43] Bump attrs from 25.1.0 to 25.2.0 (#10537) Bumps [attrs](https://github.com/sponsors/hynek) from 25.1.0 to 25.2.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=attrs&package-manager=pip&previous-version=25.1.0&new-version=25.2.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 de111dd8268..d4ee6ef8c8f 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,7 +12,7 @@ aiosignal==1.3.2 # via -r requirements/runtime-deps.in async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in -attrs==25.1.0 +attrs==25.2.0 # via -r requirements/runtime-deps.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 184642b29bb..7da904d3412 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -22,7 +22,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via # -r requirements/runtime-deps.in # valkey -attrs==25.1.0 +attrs==25.2.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx diff --git a/requirements/dev.txt b/requirements/dev.txt index 30afd855beb..d2c3960bae9 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -22,7 +22,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via # -r requirements/runtime-deps.in # valkey -attrs==25.1.0 +attrs==25.2.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx diff --git a/requirements/runtime-deps.txt b/requirements/runtime-deps.txt index 128b0ed2d6f..1f60317174d 100644 --- a/requirements/runtime-deps.txt +++ b/requirements/runtime-deps.txt @@ -12,7 +12,7 @@ aiosignal==1.3.2 # via -r requirements/runtime-deps.in async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in -attrs==25.1.0 +attrs==25.2.0 # via -r requirements/runtime-deps.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in diff --git a/requirements/test.txt b/requirements/test.txt index ea0451e9ea6..53cee8b83e5 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 -attrs==25.1.0 +attrs==25.2.0 # via -r requirements/runtime-deps.in blockbuster==1.5.23 # via -r requirements/test.in From 532cf6548c88b86551d88b22d98a74f46f57b4b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 10:54:35 +0000 Subject: [PATCH 18/43] Bump stamina from 24.3.0 to 25.1.0 (#10538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [stamina](https://github.com/hynek/stamina) from 24.3.0 to 25.1.0.
Release notes

Sourced from stamina's releases.

25.1.0

Highlights

The context manager edition! You can now use stamina.set_testing() as a context manager and also return one from an instrumentation retry hook which is entered and exited before and after sleep which allows you to emit spans for back off times!

Full changelog below!

Special Thanks

This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!

Above and Beyond

Variomedia AG (@variomedia), Tidelift (@tidelift), Ecosystems (@ecosyste-ms), Klaviyo (@klaviyo), Privacy Solutions GmbH (@privacy-solutions), FilePreviews (@filepreviews), nate nowack (@zzstoatzz), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).

Maintenance Sustainers

Buttondown (@buttondown), Christopher Dignam (@chdsbd), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Polar (@polarsource), Mike Fiedler (@miketheman), Duncan Hill (@cricalix), Colin Marquardt (@cmarqu), Pieter Swinkels (@swinkels), Nick Libertini (@libertininick), Brian M. Dennis (@crossjam), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), The Westervelt Company (@westerveltco), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Thomas Klinger (@thmsklngr), Andreas Poehlmann (@ap--), August Trapper Bigelow (@atbigelow), Carlton Gibson (@carltongibson), and Roboflow (@roboflow).

Not to forget 14 more amazing humans who chose to be generous but anonymous!

Full Changelog

Added

  • cap argument to stamina.set_testing(). By default, the value passed as attempts is used strictly. When cap=True, it is used as an upper cap; that means that if the original attempts number is lower, it's not changed. #80

  • stamina.set_testing() can now be used as a context manager. #94

  • Instrumentation hooks can now can return context managers. If they do, they are entered when a retry is scheduled and exited right before the retry is attempted. #95


This release contains contributions from @​hynek and @​sparkiegeek.

Artifact Attestations

You can verify this release's artifact attestions using GitHub's CLI tool by downloading the sdist and wheel from PyPI and running:

$ gh attestation verify --owner hynek
stamina-25.1.0.tar.gz

and

... (truncated)

Changelog

Sourced from stamina's changelog.

25.1.0 - 2025-03-12

Added

  • cap argument to stamina.set_testing(). By default, the value passed as attempts is used strictly. When cap=True, it is used as an upper cap; that means that if the original attempts number is lower, it's not changed. #80

  • stamina.set_testing() can now be used as a context manager. #94

  • Instrumentation hooks can now can return context managers. If they do, they are entered when a retry is scheduled and exited right before the retry is attempted. #95

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=stamina&package-manager=pip&previous-version=24.3.0&new-version=25.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 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 7da904d3412..24e0145ccd6 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -234,7 +234,7 @@ sphinxcontrib-spelling==8.0.1 ; platform_system != "Windows" # via -r requirements/doc-spelling.in sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in -stamina==24.3.0 +stamina==25.1.0 # via cherry-picker tenacity==9.0.0 # via stamina diff --git a/requirements/dev.txt b/requirements/dev.txt index d2c3960bae9..e5c130da871 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -225,7 +225,7 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-towncrier==0.5.0a0 # via -r requirements/doc.in -stamina==24.3.0 +stamina==25.1.0 # via cherry-picker tenacity==9.0.0 # via stamina From 0b17481eda21b9a7f7c08341520b12987f51c4a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 23:53:28 +0000 Subject: [PATCH 19/43] Bump aiohappyeyeballs from 2.5.0 to 2.6.1 (#10539) Bumps [aiohappyeyeballs](https://github.com/aio-libs/aiohappyeyeballs) from 2.5.0 to 2.6.1.
Release notes

Sourced from aiohappyeyeballs's releases.

v2.6.1 (2025-03-12)

Bug Fixes

  • Resolve TypeError on import for Python < 3.9.2 (#151, 2042c82)

Detailed Changes: v2.6.0...v2.6.1

v2.6.0 (2025-03-11)

Features

Creates an api_reference.rst file to expose the existing documentation for the few functions that have docstrings, as well as add documentation for AddrInfoType and SocketFactoryType. Now, these can be properly pointed to by other projects' documentation.


Detailed Changes: v2.5.0...v2.6.0

Changelog

Sourced from aiohappyeyeballs's changelog.

v2.6.1 (2025-03-12)

Bug fixes

  • Resolve typeerror on import for python < 3.9.2 (#151) (2042c82)

v2.6.0 (2025-03-11)

Features

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohappyeyeballs&package-manager=pip&previous-version=2.5.0&new-version=2.6.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/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 d4ee6ef8c8f..e76578f430c 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.5.0 +aiohappyeyeballs==2.6.1 # 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 24e0145ccd6..49e6f58d6f1 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.5.0 +aiohappyeyeballs==2.6.1 # 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 e5c130da871..6c6d5274712 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.5.0 +aiohappyeyeballs==2.6.1 # 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 1f60317174d..dd279106314 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.5.0 +aiohappyeyeballs==2.6.1 # 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 53cee8b83e5..81f10090fbb 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.5.0 +aiohappyeyeballs==2.6.1 # via -r requirements/runtime-deps.in aiosignal==1.3.2 # via -r requirements/runtime-deps.in From 1f309113c09e2873a803c0b85b0a4bbc3aa82979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 05:42:59 +0000 Subject: [PATCH 20/43] Bump attrs from 25.2.0 to 25.3.0 (#10546) Bumps [attrs](https://github.com/sponsors/hynek) from 25.2.0 to 25.3.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=attrs&package-manager=pip&previous-version=25.2.0&new-version=25.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 e76578f430c..db4712426a9 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,7 +12,7 @@ aiosignal==1.3.2 # via -r requirements/runtime-deps.in async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in -attrs==25.2.0 +attrs==25.3.0 # via -r requirements/runtime-deps.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 49e6f58d6f1..e744bc6f708 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -22,7 +22,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via # -r requirements/runtime-deps.in # valkey -attrs==25.2.0 +attrs==25.3.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx diff --git a/requirements/dev.txt b/requirements/dev.txt index 6c6d5274712..c1cd350baf5 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -22,7 +22,7 @@ async-timeout==5.0.1 ; python_version < "3.11" # via # -r requirements/runtime-deps.in # valkey -attrs==25.2.0 +attrs==25.3.0 # via -r requirements/runtime-deps.in babel==2.17.0 # via sphinx diff --git a/requirements/runtime-deps.txt b/requirements/runtime-deps.txt index dd279106314..c3863f8e5e3 100644 --- a/requirements/runtime-deps.txt +++ b/requirements/runtime-deps.txt @@ -12,7 +12,7 @@ aiosignal==1.3.2 # via -r requirements/runtime-deps.in async-timeout==5.0.1 ; python_version < "3.11" # via -r requirements/runtime-deps.in -attrs==25.2.0 +attrs==25.3.0 # via -r requirements/runtime-deps.in brotli==1.1.0 ; platform_python_implementation == "CPython" # via -r requirements/runtime-deps.in diff --git a/requirements/test.txt b/requirements/test.txt index 81f10090fbb..fb20a21e251 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 -attrs==25.2.0 +attrs==25.3.0 # via -r requirements/runtime-deps.in blockbuster==1.5.23 # via -r requirements/test.in From e9b657fa110d7d11a9782ea6b5e9ba162ab88317 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 05:43:03 +0000 Subject: [PATCH 21/43] Bump filelock from 3.17.0 to 3.18.0 (#10547) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.17.0 to 3.18.0.
Release notes

Sourced from filelock's releases.

3.18.0

What's Changed

New Contributors

Full Changelog: https://github.com/tox-dev/filelock/compare/3.17.0...3.18.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=filelock&package-manager=pip&previous-version=3.17.0&new-version=3.18.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 e744bc6f708..4f88e08420a 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -72,7 +72,7 @@ exceptiongroup==1.2.2 # via pytest execnet==2.1.1 # via pytest-xdist -filelock==3.17.0 +filelock==3.18.0 # via virtualenv forbiddenfruit==0.1.4 # via blockbuster diff --git a/requirements/dev.txt b/requirements/dev.txt index c1cd350baf5..1a70923b154 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -70,7 +70,7 @@ exceptiongroup==1.2.2 # via pytest execnet==2.1.1 # via pytest-xdist -filelock==3.17.0 +filelock==3.18.0 # via virtualenv forbiddenfruit==0.1.4 # via blockbuster diff --git a/requirements/lint.txt b/requirements/lint.txt index d25a756f73e..964750637c3 100644 --- a/requirements/lint.txt +++ b/requirements/lint.txt @@ -27,7 +27,7 @@ distlib==0.3.9 # via virtualenv exceptiongroup==1.2.2 # via pytest -filelock==3.17.0 +filelock==3.18.0 # via virtualenv forbiddenfruit==0.1.4 # via blockbuster From 7205661affce22fb8978d670342898295c265d43 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:29:12 +0000 Subject: [PATCH 22/43] [PR #10553/55c5f1fc backport][3.11] Add benchmark for JSON post requests that check the content type (#10554) **This is a backport of PR #10553 as merged into master (55c5f1fc16e61f576f05d31c1f9bbd324943729c).** ## What do these changes do? Add benchmark for JSON post requests that check the content type ## Are there changes in behavior for the user? no ## Is it a substantial burden for the maintainers to support this? no Co-authored-by: J. Nick Koston --- tests/test_benchmarks_client.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/test_benchmarks_client.py b/tests/test_benchmarks_client.py index ac3131e9750..ae89bc1f667 100644 --- a/tests/test_benchmarks_client.py +++ b/tests/test_benchmarks_client.py @@ -319,3 +319,30 @@ async def run_client_benchmark() -> None: @benchmark def _run() -> None: loop.run_until_complete(run_client_benchmark()) + + +def test_one_hundred_json_post_requests( + loop: asyncio.AbstractEventLoop, + aiohttp_client: AiohttpClient, + benchmark: BenchmarkFixture, +) -> None: + """Benchmark 100 JSON POST requests that check the content-type.""" + message_count = 100 + + async def handler(request: web.Request) -> web.Response: + _ = request.content_type + _ = request.charset + return web.Response() + + app = web.Application() + app.router.add_route("POST", "/", handler) + + async def run_client_benchmark() -> None: + client = await aiohttp_client(app) + for _ in range(message_count): + await client.post("/", json={"key": "value"}) + await client.close() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_client_benchmark()) From f39062116245f15b58889dea03aaf710de28a8e1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:41:35 +0000 Subject: [PATCH 23/43] [PR #10553/55c5f1fc backport][3.12] Add benchmark for JSON post requests that check the content type (#10555) **This is a backport of PR #10553 as merged into master (55c5f1fc16e61f576f05d31c1f9bbd324943729c).** ## What do these changes do? Add benchmark for JSON post requests that check the content type ## Are there changes in behavior for the user? no ## Is it a substantial burden for the maintainers to support this? no Co-authored-by: J. Nick Koston --- tests/test_benchmarks_client.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/test_benchmarks_client.py b/tests/test_benchmarks_client.py index ac3131e9750..ae89bc1f667 100644 --- a/tests/test_benchmarks_client.py +++ b/tests/test_benchmarks_client.py @@ -319,3 +319,30 @@ async def run_client_benchmark() -> None: @benchmark def _run() -> None: loop.run_until_complete(run_client_benchmark()) + + +def test_one_hundred_json_post_requests( + loop: asyncio.AbstractEventLoop, + aiohttp_client: AiohttpClient, + benchmark: BenchmarkFixture, +) -> None: + """Benchmark 100 JSON POST requests that check the content-type.""" + message_count = 100 + + async def handler(request: web.Request) -> web.Response: + _ = request.content_type + _ = request.charset + return web.Response() + + app = web.Application() + app.router.add_route("POST", "/", handler) + + async def run_client_benchmark() -> None: + client = await aiohttp_client(app) + for _ in range(message_count): + await client.post("/", json={"key": "value"}) + await client.close() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_client_benchmark()) From 928e6d70480c662d7e3a84a8b9615c2d9f1b46ac Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 23:21:49 +0000 Subject: [PATCH 24/43] [PR #10552/44e669be backport][3.11] Cache parsing of the content-type (#10557) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **This is a backport of PR #10552 as merged into master (44e669be1ab1a60c40183f92f172670d912cb834).** ## What do these changes do? When profiling some frequent POST requests, I found the bulk of the time was spent parsing the content-type string. Use the same strategy as we do for `parse_mimetype` to cache the parsing. ## Are there changes in behavior for the user? performance improvement ## Is it a substantial burden for the maintainers to support this? no ## Related issue number ## Checklist - [x] I think the code is well written - [ ] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Screenshot 2025-03-15 at 11 25 10 AM Co-authored-by: J. Nick Koston --- CHANGES/10552.misc.rst | 1 + aiohttp/helpers.py | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 CHANGES/10552.misc.rst diff --git a/CHANGES/10552.misc.rst b/CHANGES/10552.misc.rst new file mode 100644 index 00000000000..6755cbf7396 --- /dev/null +++ b/CHANGES/10552.misc.rst @@ -0,0 +1 @@ +Improved performance of parsing content types by adding a cache in the same manner currently done with mime types -- by :user:`bdraco`. diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index 8038931ebec..ace4f0e9b53 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -21,7 +21,7 @@ from email.utils import parsedate from math import ceil from pathlib import Path -from types import TracebackType +from types import MappingProxyType, TracebackType from typing import ( Any, Callable, @@ -357,6 +357,20 @@ def parse_mimetype(mimetype: str) -> MimeType: ) +@functools.lru_cache(maxsize=56) +def parse_content_type(raw: str) -> Tuple[str, MappingProxyType[str, str]]: + """Parse Content-Type header. + + Returns a tuple of the parsed content type and a + MappingProxyType of parameters. + """ + msg = HeaderParser().parsestr(f"Content-Type: {raw}") + content_type = msg.get_content_type() + params = msg.get_params(()) + content_dict = dict(params[1:]) # First element is content type again + return content_type, MappingProxyType(content_dict) + + def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]: name = getattr(obj, "name", None) if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">": @@ -710,10 +724,10 @@ def _parse_content_type(self, raw: Optional[str]) -> None: self._content_type = "application/octet-stream" self._content_dict = {} else: - msg = HeaderParser().parsestr("Content-Type: " + raw) - self._content_type = msg.get_content_type() - params = msg.get_params(()) - self._content_dict = dict(params[1:]) # First element is content type again + content_type, content_mapping_proxy = parse_content_type(raw) + self._content_type = content_type + # _content_dict needs to be mutable so we can update it + self._content_dict = content_mapping_proxy.copy() @property def content_type(self) -> str: From a95e38f78ce424575ea4667e16139a9926c55155 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 23:28:25 +0000 Subject: [PATCH 25/43] [PR #10552/44e669be backport][3.12] Cache parsing of the content-type (#10558) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **This is a backport of PR #10552 as merged into master (44e669be1ab1a60c40183f92f172670d912cb834).** ## What do these changes do? When profiling some frequent POST requests, I found the bulk of the time was spent parsing the content-type string. Use the same strategy as we do for `parse_mimetype` to cache the parsing. ## Are there changes in behavior for the user? performance improvement ## Is it a substantial burden for the maintainers to support this? no ## Related issue number ## Checklist - [x] I think the code is well written - [ ] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Screenshot 2025-03-15 at 11 25 10 AM Co-authored-by: J. Nick Koston --- CHANGES/10552.misc.rst | 1 + aiohttp/helpers.py | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 CHANGES/10552.misc.rst diff --git a/CHANGES/10552.misc.rst b/CHANGES/10552.misc.rst new file mode 100644 index 00000000000..6755cbf7396 --- /dev/null +++ b/CHANGES/10552.misc.rst @@ -0,0 +1 @@ +Improved performance of parsing content types by adding a cache in the same manner currently done with mime types -- by :user:`bdraco`. diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index 8038931ebec..ace4f0e9b53 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -21,7 +21,7 @@ from email.utils import parsedate from math import ceil from pathlib import Path -from types import TracebackType +from types import MappingProxyType, TracebackType from typing import ( Any, Callable, @@ -357,6 +357,20 @@ def parse_mimetype(mimetype: str) -> MimeType: ) +@functools.lru_cache(maxsize=56) +def parse_content_type(raw: str) -> Tuple[str, MappingProxyType[str, str]]: + """Parse Content-Type header. + + Returns a tuple of the parsed content type and a + MappingProxyType of parameters. + """ + msg = HeaderParser().parsestr(f"Content-Type: {raw}") + content_type = msg.get_content_type() + params = msg.get_params(()) + content_dict = dict(params[1:]) # First element is content type again + return content_type, MappingProxyType(content_dict) + + def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]: name = getattr(obj, "name", None) if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">": @@ -710,10 +724,10 @@ def _parse_content_type(self, raw: Optional[str]) -> None: self._content_type = "application/octet-stream" self._content_dict = {} else: - msg = HeaderParser().parsestr("Content-Type: " + raw) - self._content_type = msg.get_content_type() - params = msg.get_params(()) - self._content_dict = dict(params[1:]) # First element is content type again + content_type, content_mapping_proxy = parse_content_type(raw) + self._content_type = content_type + # _content_dict needs to be mutable so we can update it + self._content_dict = content_mapping_proxy.copy() @property def content_type(self) -> str: From e9f3f03144451d65eac6bf4cf782a7f8b89e820a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 00:02:33 +0000 Subject: [PATCH 26/43] [PR #10529/492f63dc backport][3.11] Fixed bug that lead to infinite wait for dns futures (#10559) **This is a backport of PR #10529 as merged into master (492f63dc252e76ce892e459081286fb46bde87cf).** ## What do these changes do? Fixed bug that lead to infinite wait for dns futures when exception occured in trace.send_dns_cache_miss call. ## Are there changes in behavior for the user? No ## Is it a substantial burden for the maintainers to support this? No ## Related issue number No issue. ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Co-authored-by: Alexey Stavrov --- CHANGES/10529.bugfix.rst | 2 ++ CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 6 ++--- tests/test_connector.py | 55 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 CHANGES/10529.bugfix.rst diff --git a/CHANGES/10529.bugfix.rst b/CHANGES/10529.bugfix.rst new file mode 100644 index 00000000000..d6714ffd043 --- /dev/null +++ b/CHANGES/10529.bugfix.rst @@ -0,0 +1,2 @@ +Fixed an issue where dns queries were delayed indefinitely when an exception occurred in a ``trace.send_dns_cache_miss`` +-- by :user:`logioniz`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 1f0d1e7d2d7..953af52498a 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -31,6 +31,7 @@ Alexandru Mihai Alexey Firsov Alexey Nikitin Alexey Popravka +Alexey Stavrov Alexey Stepanov Amin Etesamian Amit Tulshyan diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 14433ba37e1..b3a918b3cee 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1015,11 +1015,11 @@ async def _resolve_host_with_throttle( This method must be run in a task and shielded from cancellation to avoid cancelling the underlying lookup. """ - if traces: - for trace in traces: - await trace.send_dns_cache_miss(host) try: if traces: + for trace in traces: + await trace.send_dns_cache_miss(host) + for trace in traces: await trace.send_dns_resolvehost_start(host) diff --git a/tests/test_connector.py b/tests/test_connector.py index e79b36a673d..e8cc46c54d2 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -3497,6 +3497,61 @@ async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None: await connector.close() +async def test_connector_resolve_in_case_of_trace_cache_miss_exception( + loop: asyncio.AbstractEventLoop, +) -> None: + token: ResolveResult = { + "hostname": "localhost", + "host": "127.0.0.1", + "port": 80, + "family": socket.AF_INET, + "proto": 0, + "flags": socket.AI_NUMERICHOST, + } + + request_count = 0 + + class DummyTracer(Trace): + def __init__(self) -> None: + """Dummy""" + + async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None: + """Dummy send_dns_cache_hit""" + + async def send_dns_resolvehost_start( + self, *args: object, **kwargs: object + ) -> None: + """Dummy send_dns_resolvehost_start""" + + async def send_dns_resolvehost_end( + self, *args: object, **kwargs: object + ) -> None: + """Dummy send_dns_resolvehost_end""" + + async def send_dns_cache_miss(self, *args: object, **kwargs: object) -> None: + nonlocal request_count + request_count += 1 + if request_count <= 1: + raise Exception("first attempt") + + async def resolve_response() -> List[ResolveResult]: + await asyncio.sleep(0) + return [token] + + with mock.patch("aiohttp.connector.DefaultResolver") as m_resolver: + m_resolver().resolve.return_value = resolve_response() + + connector = TCPConnector() + traces = [DummyTracer()] + + with pytest.raises(Exception): + await connector._resolve_host("", 0, traces) + + await connector._resolve_host("", 0, traces) == [token] + + await connector.close() + + async def test_connector_does_not_remove_needed_waiters( loop: asyncio.AbstractEventLoop, key: ConnectionKey ) -> None: From 25c9ab8b727db02188500471719275755d7849cc Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 00:06:40 +0000 Subject: [PATCH 27/43] [PR #10529/492f63dc backport][3.12] Fixed bug that lead to infinite wait for dns futures (#10560) **This is a backport of PR #10529 as merged into master (492f63dc252e76ce892e459081286fb46bde87cf).** ## What do these changes do? Fixed bug that lead to infinite wait for dns futures when exception occured in trace.send_dns_cache_miss call. ## Are there changes in behavior for the user? No ## Is it a substantial burden for the maintainers to support this? No ## Related issue number No issue. ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Co-authored-by: Alexey Stavrov --- CHANGES/10529.bugfix.rst | 2 ++ CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 6 ++--- tests/test_connector.py | 55 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 CHANGES/10529.bugfix.rst diff --git a/CHANGES/10529.bugfix.rst b/CHANGES/10529.bugfix.rst new file mode 100644 index 00000000000..d6714ffd043 --- /dev/null +++ b/CHANGES/10529.bugfix.rst @@ -0,0 +1,2 @@ +Fixed an issue where dns queries were delayed indefinitely when an exception occurred in a ``trace.send_dns_cache_miss`` +-- by :user:`logioniz`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index fb5217e3e6b..4c44c5f4001 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -31,6 +31,7 @@ Alexandru Mihai Alexey Firsov Alexey Nikitin Alexey Popravka +Alexey Stavrov Alexey Stepanov Amin Etesamian Amit Tulshyan diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 75d5796f7d2..081ff330d38 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1025,11 +1025,11 @@ async def _resolve_host_with_throttle( This method must be run in a task and shielded from cancellation to avoid cancelling the underlying lookup. """ - if traces: - for trace in traces: - await trace.send_dns_cache_miss(host) try: if traces: + for trace in traces: + await trace.send_dns_cache_miss(host) + for trace in traces: await trace.send_dns_resolvehost_start(host) diff --git a/tests/test_connector.py b/tests/test_connector.py index b7531361287..b199d9b5703 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -3497,6 +3497,61 @@ async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None: await connector.close() +async def test_connector_resolve_in_case_of_trace_cache_miss_exception( + loop: asyncio.AbstractEventLoop, +) -> None: + token: ResolveResult = { + "hostname": "localhost", + "host": "127.0.0.1", + "port": 80, + "family": socket.AF_INET, + "proto": 0, + "flags": socket.AI_NUMERICHOST, + } + + request_count = 0 + + class DummyTracer(Trace): + def __init__(self) -> None: + """Dummy""" + + async def send_dns_cache_hit(self, *args: object, **kwargs: object) -> None: + """Dummy send_dns_cache_hit""" + + async def send_dns_resolvehost_start( + self, *args: object, **kwargs: object + ) -> None: + """Dummy send_dns_resolvehost_start""" + + async def send_dns_resolvehost_end( + self, *args: object, **kwargs: object + ) -> None: + """Dummy send_dns_resolvehost_end""" + + async def send_dns_cache_miss(self, *args: object, **kwargs: object) -> None: + nonlocal request_count + request_count += 1 + if request_count <= 1: + raise Exception("first attempt") + + async def resolve_response() -> List[ResolveResult]: + await asyncio.sleep(0) + return [token] + + with mock.patch("aiohttp.connector.DefaultResolver") as m_resolver: + m_resolver().resolve.return_value = resolve_response() + + connector = TCPConnector() + traces = [DummyTracer()] + + with pytest.raises(Exception): + await connector._resolve_host("", 0, traces) + + await connector._resolve_host("", 0, traces) == [token] + + await connector.close() + + async def test_connector_does_not_remove_needed_waiters( loop: asyncio.AbstractEventLoop, key: ConnectionKey ) -> None: From 6357c055f543908dbaf167422231c09877e9b955 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 00:45:45 +0000 Subject: [PATCH 28/43] [PR #10551/d067260d backport][3.11] Re-raise OSError as ClientConnectionError when failing to explicitly close connector socket (#10561) **This is a backport of PR #10551 as merged into master (d067260df75e4d04a23a0481cf9cf8f7194c80f1).** ## What do these changes do? This is a followup to #10464 to handle the case where `socket.close()` can also raise. This matches the logic we have in aiohappyeyeballs: https://github.com/aio-libs/aiohappyeyeballs/blob/e3bd5bdf44f5d187802de6dcb08d27e1ca6da048/src/aiohappyeyeballs/impl.py#L227 We shouldn't raising `OSError` externally from this method as callers expect a `ClientError` ## Are there changes in behavior for the user? bugfix ## Is it a substantial burden for the maintainers to support this? no ## Related issue number fixes #10506 ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Co-authored-by: J. Nick Koston --- CHANGES/10551.bugfix.rst | 1 + aiohttp/connector.py | 5 ++++- tests/test_connector.py | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10551.bugfix.rst diff --git a/CHANGES/10551.bugfix.rst b/CHANGES/10551.bugfix.rst new file mode 100644 index 00000000000..8f3eb24d6ae --- /dev/null +++ b/CHANGES/10551.bugfix.rst @@ -0,0 +1 @@ +The connector now raises :exc:`aiohttp.ClientConnectionError` instead of :exc:`OSError` when failing to explicitly close the socket after :py:meth:`asyncio.loop.create_connection` fails -- by :user:`bdraco`. diff --git a/aiohttp/connector.py b/aiohttp/connector.py index b3a918b3cee..e5cf3674cba 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1138,7 +1138,10 @@ async def _wrap_create_connection( # 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() + try: + sock.close() + except OSError as exc: + raise client_error(req.connection_key, exc) from exc async def _wrap_existing_connection( self, diff --git a/tests/test_connector.py b/tests/test_connector.py index e8cc46c54d2..a86a2417423 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -640,6 +640,33 @@ async def test_tcp_connector_closes_socket_on_error( await conn.close() +async def test_tcp_connector_closes_socket_on_error_results_in_another_error( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + """Test that when error occurs while closing the socket.""" + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + start_connection.return_value.close.side_effect = OSError( + 1, "error from closing socket" + ) + + conn = aiohttp.TCPConnector() + with ( + mock.patch.object( + conn._loop, + "create_connection", + autospec=True, + spec_set=True, + side_effect=ValueError, + ), + pytest.raises(aiohttp.ClientConnectionError, match="error from closing socket"), + ): + 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: From a3c36ad3dd11bbf916cd673ca8c480db90361f12 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 01:02:06 +0000 Subject: [PATCH 29/43] [PR #10551/d067260d backport][3.12] Re-raise OSError as ClientConnectionError when failing to explicitly close connector socket (#10562) **This is a backport of PR #10551 as merged into master (d067260df75e4d04a23a0481cf9cf8f7194c80f1).** ## What do these changes do? This is a followup to #10464 to handle the case where `socket.close()` can also raise. This matches the logic we have in aiohappyeyeballs: https://github.com/aio-libs/aiohappyeyeballs/blob/e3bd5bdf44f5d187802de6dcb08d27e1ca6da048/src/aiohappyeyeballs/impl.py#L227 We shouldn't raising `OSError` externally from this method as callers expect a `ClientError` ## Are there changes in behavior for the user? bugfix ## Is it a substantial burden for the maintainers to support this? no ## Related issue number fixes #10506 ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Co-authored-by: J. Nick Koston --- CHANGES/10551.bugfix.rst | 1 + aiohttp/connector.py | 5 ++++- tests/test_connector.py | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 CHANGES/10551.bugfix.rst diff --git a/CHANGES/10551.bugfix.rst b/CHANGES/10551.bugfix.rst new file mode 100644 index 00000000000..8f3eb24d6ae --- /dev/null +++ b/CHANGES/10551.bugfix.rst @@ -0,0 +1 @@ +The connector now raises :exc:`aiohttp.ClientConnectionError` instead of :exc:`OSError` when failing to explicitly close the socket after :py:meth:`asyncio.loop.create_connection` fails -- by :user:`bdraco`. diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 081ff330d38..de9062e8ae3 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -1150,7 +1150,10 @@ async def _wrap_create_connection( # 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() + try: + sock.close() + except OSError as exc: + raise client_error(req.connection_key, exc) from exc async def _wrap_existing_connection( self, diff --git a/tests/test_connector.py b/tests/test_connector.py index b199d9b5703..2aaa50985a1 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -640,6 +640,33 @@ async def test_tcp_connector_closes_socket_on_error( await conn.close() +async def test_tcp_connector_closes_socket_on_error_results_in_another_error( + loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock +) -> None: + """Test that when error occurs while closing the socket.""" + req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop) + start_connection.return_value.close.side_effect = OSError( + 1, "error from closing socket" + ) + + conn = aiohttp.TCPConnector() + with ( + mock.patch.object( + conn._loop, + "create_connection", + autospec=True, + spec_set=True, + side_effect=ValueError, + ), + pytest.raises(aiohttp.ClientConnectionError, match="error from closing socket"), + ): + 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: From 077e4fa7680f75d9928a333e3d838896a7027af0 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 11:39:32 -1000 Subject: [PATCH 30/43] [PR #10556/9d4e1161 backport][3.12] Break cyclic references at connection close when there was a traceback (#10567) **This is a backport of PR #10556 as merged into master (9d4e11617a1e596926d11e483280183224fc7ee6).** ## What do these changes do? Clears the exception on the `DataQueue` and `WebSocketDataQueue` when the connection is closed to break cyclic references. ## Are there changes in behavior for the user? bugfix ## Is it a substantial burden for the maintainers to support this? no ## Related issue number fixes #10535 ## Checklist - [ ] I think the code is well written - [ ] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Co-authored-by: J. Nick Koston --- CHANGES/10556.bugfix.rst | 3 ++ aiohttp/_websocket/reader_py.py | 1 + aiohttp/client_proto.py | 1 + .../check_for_client_response_leak.py | 47 +++++++++++++++++++ tests/test_leaks.py | 25 ++++++++++ 5 files changed, 77 insertions(+) create mode 100644 CHANGES/10556.bugfix.rst create mode 100644 tests/isolated/check_for_client_response_leak.py create mode 100644 tests/test_leaks.py diff --git a/CHANGES/10556.bugfix.rst b/CHANGES/10556.bugfix.rst new file mode 100644 index 00000000000..aad4eccbe48 --- /dev/null +++ b/CHANGES/10556.bugfix.rst @@ -0,0 +1,3 @@ +Break cyclic references at connection close when there was a traceback -- by :user:`bdraco`. + +Special thanks to :user:`availov` for reporting the issue. diff --git a/aiohttp/_websocket/reader_py.py b/aiohttp/_websocket/reader_py.py index 94d20010890..1645b3949b1 100644 --- a/aiohttp/_websocket/reader_py.py +++ b/aiohttp/_websocket/reader_py.py @@ -93,6 +93,7 @@ def _release_waiter(self) -> None: def feed_eof(self) -> None: self._eof = True self._release_waiter() + self._exception = None # Break cyclic references def feed_data(self, data: "WSMessage", size: "int_") -> None: self._size += size diff --git a/aiohttp/client_proto.py b/aiohttp/client_proto.py index 79f033e3e12..2d64b3f3644 100644 --- a/aiohttp/client_proto.py +++ b/aiohttp/client_proto.py @@ -64,6 +64,7 @@ def force_close(self) -> None: self._should_close = True def close(self) -> None: + self._exception = None # Break cyclic references transport = self.transport if transport is not None: transport.close() diff --git a/tests/isolated/check_for_client_response_leak.py b/tests/isolated/check_for_client_response_leak.py new file mode 100644 index 00000000000..67393c2c2d8 --- /dev/null +++ b/tests/isolated/check_for_client_response_leak.py @@ -0,0 +1,47 @@ +import asyncio +import contextlib +import gc +import sys + +from aiohttp import ClientError, ClientSession, web +from aiohttp.test_utils import get_unused_port_socket + +gc.set_debug(gc.DEBUG_LEAK) + + +async def main() -> None: + app = web.Application() + + async def stream_handler(request: web.Request) -> web.Response: + assert request.transport is not None + request.transport.close() # Forcefully closing connection + return web.Response() + + app.router.add_get("/stream", stream_handler) + sock = get_unused_port_socket("127.0.0.1") + port = sock.getsockname()[1] + + runner = web.AppRunner(app) + await runner.setup() + site = web.SockSite(runner, sock) + await site.start() + + session = ClientSession() + + async def fetch_stream(url: str) -> None: + """Fetch a stream and read a few bytes from it.""" + with contextlib.suppress(ClientError): + await session.get(url) + + client_task = asyncio.create_task(fetch_stream(f"http://localhost:{port}/stream")) + await client_task + gc.collect() + client_response_present = any( + type(obj).__name__ == "ClientResponse" for obj in gc.garbage + ) + await session.close() + await runner.cleanup() + sys.exit(1 if client_response_present else 0) + + +asyncio.run(main()) diff --git a/tests/test_leaks.py b/tests/test_leaks.py new file mode 100644 index 00000000000..a3b6b624346 --- /dev/null +++ b/tests/test_leaks.py @@ -0,0 +1,25 @@ +import pathlib +import platform +import subprocess +import sys + +import pytest + +IS_PYPY = platform.python_implementation() == "PyPy" + + +@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") +def test_client_response_does_not_leak_on_server_disconnected_error() -> None: + """Test that ClientResponse is collected after server disconnects. + + https://github.com/aio-libs/aiohttp/issues/10535 + """ + leak_test_script = pathlib.Path(__file__).parent.joinpath( + "isolated", "check_for_client_response_leak.py" + ) + + with subprocess.Popen( + [sys.executable, "-u", str(leak_test_script)], + stdout=subprocess.PIPE, + ) as proc: + assert proc.wait() == 0, "ClientResponse leaked" From 771d203472fa356c4f53dde30c5ae94212817838 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 11:39:44 -1000 Subject: [PATCH 31/43] [PR #10556/9d4e1161 backport][3.11] Break cyclic references at connection close when there was a traceback (#10566) **This is a backport of PR #10556 as merged into master (9d4e11617a1e596926d11e483280183224fc7ee6).** ## What do these changes do? Clears the exception on the `DataQueue` and `WebSocketDataQueue` when the connection is closed to break cyclic references. ## Are there changes in behavior for the user? bugfix ## Is it a substantial burden for the maintainers to support this? no ## Related issue number fixes #10535 ## Checklist - [ ] I think the code is well written - [ ] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Co-authored-by: J. Nick Koston --- CHANGES/10556.bugfix.rst | 3 ++ aiohttp/_websocket/reader_py.py | 1 + aiohttp/client_proto.py | 1 + .../check_for_client_response_leak.py | 47 +++++++++++++++++++ tests/test_leaks.py | 25 ++++++++++ 5 files changed, 77 insertions(+) create mode 100644 CHANGES/10556.bugfix.rst create mode 100644 tests/isolated/check_for_client_response_leak.py create mode 100644 tests/test_leaks.py diff --git a/CHANGES/10556.bugfix.rst b/CHANGES/10556.bugfix.rst new file mode 100644 index 00000000000..aad4eccbe48 --- /dev/null +++ b/CHANGES/10556.bugfix.rst @@ -0,0 +1,3 @@ +Break cyclic references at connection close when there was a traceback -- by :user:`bdraco`. + +Special thanks to :user:`availov` for reporting the issue. diff --git a/aiohttp/_websocket/reader_py.py b/aiohttp/_websocket/reader_py.py index 94d20010890..1645b3949b1 100644 --- a/aiohttp/_websocket/reader_py.py +++ b/aiohttp/_websocket/reader_py.py @@ -93,6 +93,7 @@ def _release_waiter(self) -> None: def feed_eof(self) -> None: self._eof = True self._release_waiter() + self._exception = None # Break cyclic references def feed_data(self, data: "WSMessage", size: "int_") -> None: self._size += size diff --git a/aiohttp/client_proto.py b/aiohttp/client_proto.py index 79f033e3e12..2d64b3f3644 100644 --- a/aiohttp/client_proto.py +++ b/aiohttp/client_proto.py @@ -64,6 +64,7 @@ def force_close(self) -> None: self._should_close = True def close(self) -> None: + self._exception = None # Break cyclic references transport = self.transport if transport is not None: transport.close() diff --git a/tests/isolated/check_for_client_response_leak.py b/tests/isolated/check_for_client_response_leak.py new file mode 100644 index 00000000000..67393c2c2d8 --- /dev/null +++ b/tests/isolated/check_for_client_response_leak.py @@ -0,0 +1,47 @@ +import asyncio +import contextlib +import gc +import sys + +from aiohttp import ClientError, ClientSession, web +from aiohttp.test_utils import get_unused_port_socket + +gc.set_debug(gc.DEBUG_LEAK) + + +async def main() -> None: + app = web.Application() + + async def stream_handler(request: web.Request) -> web.Response: + assert request.transport is not None + request.transport.close() # Forcefully closing connection + return web.Response() + + app.router.add_get("/stream", stream_handler) + sock = get_unused_port_socket("127.0.0.1") + port = sock.getsockname()[1] + + runner = web.AppRunner(app) + await runner.setup() + site = web.SockSite(runner, sock) + await site.start() + + session = ClientSession() + + async def fetch_stream(url: str) -> None: + """Fetch a stream and read a few bytes from it.""" + with contextlib.suppress(ClientError): + await session.get(url) + + client_task = asyncio.create_task(fetch_stream(f"http://localhost:{port}/stream")) + await client_task + gc.collect() + client_response_present = any( + type(obj).__name__ == "ClientResponse" for obj in gc.garbage + ) + await session.close() + await runner.cleanup() + sys.exit(1 if client_response_present else 0) + + +asyncio.run(main()) diff --git a/tests/test_leaks.py b/tests/test_leaks.py new file mode 100644 index 00000000000..a3b6b624346 --- /dev/null +++ b/tests/test_leaks.py @@ -0,0 +1,25 @@ +import pathlib +import platform +import subprocess +import sys + +import pytest + +IS_PYPY = platform.python_implementation() == "PyPy" + + +@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") +def test_client_response_does_not_leak_on_server_disconnected_error() -> None: + """Test that ClientResponse is collected after server disconnects. + + https://github.com/aio-libs/aiohttp/issues/10535 + """ + leak_test_script = pathlib.Path(__file__).parent.joinpath( + "isolated", "check_for_client_response_leak.py" + ) + + with subprocess.Popen( + [sys.executable, "-u", str(leak_test_script)], + stdout=subprocess.PIPE, + ) as proc: + assert proc.wait() == 0, "ClientResponse leaked" From 6ae2570bf2b53ff07d0fac2bbf1ffe81837ef415 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 22:11:37 +0000 Subject: [PATCH 32/43] [PR #10569/dfbf782b backport][3.11] Break cyclic references when there is an exception handling a request (#10571) **This is a backport of PR #10569 as merged into master (dfbf782ba4ea3eabfe052e6224727cf83efdffb5).** ## What do these changes do? This is a partial fix for #10548 - There is still another case for `SystemRoute`s that needs to be addressed. No reproducer available yet. - There is also another case on the client side on connection refused that still needs to be addressed https://github.com/aio-libs/aiohttp/issues/10548#issuecomment-2727643763 ## Are there changes in behavior for the user? fixes memory leak ## Is it a substantial burden for the maintainers to support this? no Co-authored-by: J. Nick Koston --- CHANGES/10569.bugfix.rst | 1 + aiohttp/web_protocol.py | 14 ++++++-- tests/isolated/check_for_request_leak.py | 41 ++++++++++++++++++++++++ tests/test_leaks.py | 17 ++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 CHANGES/10569.bugfix.rst create mode 100644 tests/isolated/check_for_request_leak.py diff --git a/CHANGES/10569.bugfix.rst b/CHANGES/10569.bugfix.rst new file mode 100644 index 00000000000..7d817e867d4 --- /dev/null +++ b/CHANGES/10569.bugfix.rst @@ -0,0 +1 @@ +Break cyclic references when there is an exception handling a request -- by :user:`bdraco`. diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index e4c347e5a9e..1dba9606ea0 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -520,8 +520,6 @@ async def start(self) -> None: keep_alive(True) specified. """ loop = self._loop - handler = asyncio.current_task(loop) - assert handler is not None manager = self._manager assert manager is not None keepalive_timeout = self._keepalive_timeout @@ -551,7 +549,16 @@ async def start(self) -> None: else: request_handler = self._request_handler - request = self._request_factory(message, payload, self, writer, handler) + # Important don't hold a reference to the current task + # as on traceback it will prevent the task from being + # collected and will cause a memory leak. + request = self._request_factory( + message, + payload, + self, + writer, + self._task_handler or asyncio.current_task(loop), # type: ignore[arg-type] + ) try: # a new task is used for copy context vars (#3406) coro = self._handle_request(request, start, request_handler) @@ -617,6 +624,7 @@ async def start(self) -> None: self.force_close() raise finally: + request._task = None # type: ignore[assignment] # Break reference cycle in case of exception if self.transport is None and resp is not None: self.log_debug("Ignored premature client disconnection.") diff --git a/tests/isolated/check_for_request_leak.py b/tests/isolated/check_for_request_leak.py new file mode 100644 index 00000000000..6f340a05277 --- /dev/null +++ b/tests/isolated/check_for_request_leak.py @@ -0,0 +1,41 @@ +import asyncio +import gc +import sys +from typing import NoReturn + +from aiohttp import ClientSession, web +from aiohttp.test_utils import get_unused_port_socket + +gc.set_debug(gc.DEBUG_LEAK) + + +async def main() -> None: + app = web.Application() + + async def handler(request: web.Request) -> NoReturn: + await request.json() + assert False + + app.router.add_route("GET", "/json", handler) + sock = get_unused_port_socket("127.0.0.1") + port = sock.getsockname()[1] + + runner = web.AppRunner(app) + await runner.setup() + site = web.SockSite(runner, sock) + await site.start() + + async with ClientSession() as session: + async with session.get(f"http://127.0.0.1:{port}/json") as resp: + await resp.read() + + # Give time for the cancelled task to be collected + await asyncio.sleep(0.5) + gc.collect() + request_present = any(type(obj).__name__ == "Request" for obj in gc.garbage) + await session.close() + await runner.cleanup() + sys.exit(1 if request_present else 0) + + +asyncio.run(main()) diff --git a/tests/test_leaks.py b/tests/test_leaks.py index a3b6b624346..f527ce18cae 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -23,3 +23,20 @@ def test_client_response_does_not_leak_on_server_disconnected_error() -> None: stdout=subprocess.PIPE, ) as proc: assert proc.wait() == 0, "ClientResponse leaked" + + +@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") +def test_request_does_not_leak_when_request_handler_raises() -> None: + """Test that the Request object is collected when the handler raises. + + https://github.com/aio-libs/aiohttp/issues/10548 + """ + leak_test_script = pathlib.Path(__file__).parent.joinpath( + "isolated", "check_for_request_leak.py" + ) + + with subprocess.Popen( + [sys.executable, "-u", str(leak_test_script)], + stdout=subprocess.PIPE, + ) as proc: + assert proc.wait() == 0, "Request leaked" From 833792744a06ef725cc06804cc9a06582c6116cd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 12:26:18 -1000 Subject: [PATCH 33/43] [PR #10569/dfbf782b backport][3.12] Break cyclic references when there is an exception handling a request (#10572) **This is a backport of PR #10569 as merged into master (dfbf782ba4ea3eabfe052e6224727cf83efdffb5).** ## What do these changes do? fixes #10548 ## Are there changes in behavior for the user? fixes a potential memory leak ## Is it a substantial burden for the maintainers to support this? no Co-authored-by: J. Nick Koston --- CHANGES/10569.bugfix.rst | 1 + aiohttp/web_protocol.py | 14 ++++++-- tests/isolated/check_for_request_leak.py | 41 ++++++++++++++++++++++++ tests/test_leaks.py | 17 ++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 CHANGES/10569.bugfix.rst create mode 100644 tests/isolated/check_for_request_leak.py diff --git a/CHANGES/10569.bugfix.rst b/CHANGES/10569.bugfix.rst new file mode 100644 index 00000000000..7d817e867d4 --- /dev/null +++ b/CHANGES/10569.bugfix.rst @@ -0,0 +1 @@ +Break cyclic references when there is an exception handling a request -- by :user:`bdraco`. diff --git a/aiohttp/web_protocol.py b/aiohttp/web_protocol.py index e4c347e5a9e..1dba9606ea0 100644 --- a/aiohttp/web_protocol.py +++ b/aiohttp/web_protocol.py @@ -520,8 +520,6 @@ async def start(self) -> None: keep_alive(True) specified. """ loop = self._loop - handler = asyncio.current_task(loop) - assert handler is not None manager = self._manager assert manager is not None keepalive_timeout = self._keepalive_timeout @@ -551,7 +549,16 @@ async def start(self) -> None: else: request_handler = self._request_handler - request = self._request_factory(message, payload, self, writer, handler) + # Important don't hold a reference to the current task + # as on traceback it will prevent the task from being + # collected and will cause a memory leak. + request = self._request_factory( + message, + payload, + self, + writer, + self._task_handler or asyncio.current_task(loop), # type: ignore[arg-type] + ) try: # a new task is used for copy context vars (#3406) coro = self._handle_request(request, start, request_handler) @@ -617,6 +624,7 @@ async def start(self) -> None: self.force_close() raise finally: + request._task = None # type: ignore[assignment] # Break reference cycle in case of exception if self.transport is None and resp is not None: self.log_debug("Ignored premature client disconnection.") diff --git a/tests/isolated/check_for_request_leak.py b/tests/isolated/check_for_request_leak.py new file mode 100644 index 00000000000..6f340a05277 --- /dev/null +++ b/tests/isolated/check_for_request_leak.py @@ -0,0 +1,41 @@ +import asyncio +import gc +import sys +from typing import NoReturn + +from aiohttp import ClientSession, web +from aiohttp.test_utils import get_unused_port_socket + +gc.set_debug(gc.DEBUG_LEAK) + + +async def main() -> None: + app = web.Application() + + async def handler(request: web.Request) -> NoReturn: + await request.json() + assert False + + app.router.add_route("GET", "/json", handler) + sock = get_unused_port_socket("127.0.0.1") + port = sock.getsockname()[1] + + runner = web.AppRunner(app) + await runner.setup() + site = web.SockSite(runner, sock) + await site.start() + + async with ClientSession() as session: + async with session.get(f"http://127.0.0.1:{port}/json") as resp: + await resp.read() + + # Give time for the cancelled task to be collected + await asyncio.sleep(0.5) + gc.collect() + request_present = any(type(obj).__name__ == "Request" for obj in gc.garbage) + await session.close() + await runner.cleanup() + sys.exit(1 if request_present else 0) + + +asyncio.run(main()) diff --git a/tests/test_leaks.py b/tests/test_leaks.py index a3b6b624346..f527ce18cae 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -23,3 +23,20 @@ def test_client_response_does_not_leak_on_server_disconnected_error() -> None: stdout=subprocess.PIPE, ) as proc: assert proc.wait() == 0, "ClientResponse leaked" + + +@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") +def test_request_does_not_leak_when_request_handler_raises() -> None: + """Test that the Request object is collected when the handler raises. + + https://github.com/aio-libs/aiohttp/issues/10548 + """ + leak_test_script = pathlib.Path(__file__).parent.joinpath( + "isolated", "check_for_request_leak.py" + ) + + with subprocess.Popen( + [sys.executable, "-u", str(leak_test_script)], + stdout=subprocess.PIPE, + ) as proc: + assert proc.wait() == 0, "Request leaked" From 240fb9e7b58225f58c62bfb27cbbbf577e2b0b52 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 16 Mar 2025 12:39:33 -1000 Subject: [PATCH 34/43] [PR #10534/3b9bb1cd backport][3.12] Replace tcp_sockopts with socket_factory (#10574) replaces and closes #10565 Instead of TCPConnector taking a list of sockopts to be applied sockets created, take a socket_factory callback that allows the caller to implement socket creation entirely. Fixes #10520 Replace `tcp_sockopts` parameter with a `socket_factory` parameter that is a callback allowing the caller to own socket creation. If passed, all sockets created by `TCPConnector` are expected to come from the `socket_factory` callback. The only users to experience a change in behavior are those who are using the un-released `tcp_sockopts` argument to `TCPConnector`. However, using unreleased code comes with caveat emptor, and is why I felt entitled to remove the option entirely without warning. The burden will be minimal and would only arise if `aiohappyeyeballs` changes their interface. - [x] I think the code is well written - [x] Unit tests for the changes exist - [x] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. --------- Co-authored-by: J. Nick Koston (cherry picked from commit 3b9bb1cd5677a8c8443d16184ed36856ae105cd7) ## What do these changes do? ## Are there changes in behavior for the user? ## Is it a substantial burden for the maintainers to support this? ## Related issue number ## Checklist - [ ] I think the code is well written - [ ] Unit tests for the changes exist - [ ] Documentation reflects the changes - [ ] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [ ] Add a new news fragment into the `CHANGES/` folder * name it `..rst` (e.g. `588.bugfix.rst`) * if you don't have an issue number, change it to the pull request number after creating the PR * `.bugfix`: A bug fix for something the maintainers deemed an improper undesired behavior that got corrected to match pre-agreed expectations. * `.feature`: A new behavior, public APIs. That sort of stuff. * `.deprecation`: A declaration of future API removals and breaking changes in behavior. * `.breaking`: When something public is removed in a breaking way. Could be deprecated in an earlier release. * `.doc`: Notable updates to the documentation structure or build process. * `.packaging`: Notes for downstreams about unobvious side effects and tooling. Changes in the test invocation considerations and runtime assumptions. * `.contrib`: Stuff that affects the contributor experience. e.g. Running tests, building the docs, setting up the development environment. * `.misc`: Changes that are hard to assign to any of the above categories. * Make sure to use full sentences with correct case and punctuation, for example: ```rst Fixed issue with non-ascii contents in doctest text files -- by :user:`contributor-gh-handle`. ``` Use the past tense or the present tense a non-imperative mood, referring to what's changed compared to the last released version of this project. Co-authored-by: Tim Menninger --- CHANGES/10474.feature.rst | 2 -- CHANGES/10520.feature.rst | 2 ++ aiohttp/__init__.py | 6 ++++ aiohttp/connector.py | 29 +++++++++------ docs/client_advanced.rst | 23 +++++++----- docs/client_reference.rst | 36 ++++++++++++++++--- docs/conf.py | 3 ++ requirements/runtime-deps.in | 2 +- setup.cfg | 2 +- tests/test_connector.py | 69 ++++++++++++++++++++++++++---------- 10 files changed, 128 insertions(+), 46 deletions(-) delete mode 100644 CHANGES/10474.feature.rst create mode 100644 CHANGES/10520.feature.rst diff --git a/CHANGES/10474.feature.rst b/CHANGES/10474.feature.rst deleted file mode 100644 index d5d6e4b40b9..00000000000 --- a/CHANGES/10474.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added ``tcp_sockopts`` to ``TCPConnector`` to allow specifying custom socket options --- by :user:`TimMenninger`. diff --git a/CHANGES/10520.feature.rst b/CHANGES/10520.feature.rst new file mode 100644 index 00000000000..3d2877b5c09 --- /dev/null +++ b/CHANGES/10520.feature.rst @@ -0,0 +1,2 @@ +Added ``socket_factory`` to :py:class:`aiohttp.TCPConnector` to allow specifying custom socket options +-- by :user:`TimMenninger`. diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 49eaf4541de..66645143fc9 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -47,6 +47,10 @@ WSServerHandshakeError, request, ) +from .connector import ( + AddrInfoType as AddrInfoType, + SocketFactoryType as SocketFactoryType, +) from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar from .formdata import FormData as FormData from .helpers import BasicAuth, ChainMapProxy, ETag @@ -126,6 +130,7 @@ __all__: Tuple[str, ...] = ( "hdrs", # client + "AddrInfoType", "BaseConnector", "ClientConnectionError", "ClientConnectionResetError", @@ -161,6 +166,7 @@ "ServerDisconnectedError", "ServerFingerprintMismatch", "ServerTimeoutError", + "SocketFactoryType", "SocketTimeoutError", "TCPConnector", "TooManyRedirects", diff --git a/aiohttp/connector.py b/aiohttp/connector.py index de9062e8ae3..1c2d8d73e07 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -19,7 +19,6 @@ DefaultDict, Deque, Dict, - Iterable, Iterator, List, Literal, @@ -33,6 +32,7 @@ ) import aiohappyeyeballs +from aiohappyeyeballs import AddrInfoType, SocketFactoryType from . import hdrs, helpers from .abc import AbstractResolver, ResolveResult @@ -95,7 +95,14 @@ # which first appeared in Python 3.12.7 and 3.13.1 -__all__ = ("BaseConnector", "TCPConnector", "UnixConnector", "NamedPipeConnector") +__all__ = ( + "BaseConnector", + "TCPConnector", + "UnixConnector", + "NamedPipeConnector", + "AddrInfoType", + "SocketFactoryType", +) if TYPE_CHECKING: @@ -834,8 +841,9 @@ 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 + socket_factory - A SocketFactoryType function that, if supplied, + will be used to create sockets given an + AddrInfoType. """ allowed_protocol_schema_set = HIGH_LEVEL_SCHEMA_SET | frozenset({"tcp"}) @@ -861,7 +869,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]]] = [], + socket_factory: Optional[SocketFactoryType] = None, ): super().__init__( keepalive_timeout=keepalive_timeout, @@ -888,7 +896,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 + self._socket_factory = socket_factory def close(self) -> Awaitable[None]: """Close all ongoing DNS calls.""" @@ -1112,7 +1120,7 @@ def _get_fingerprint(self, req: ClientRequest) -> Optional["Fingerprint"]: async def _wrap_create_connection( self, *args: Any, - addr_infos: List[aiohappyeyeballs.AddrInfoType], + addr_infos: List[AddrInfoType], req: ClientRequest, timeout: "ClientTimeout", client_error: Type[Exception] = ClientConnectorError, @@ -1129,9 +1137,8 @@ async def _wrap_create_connection( happy_eyeballs_delay=self._happy_eyeballs_delay, interleave=self._interleave, loop=self._loop, + socket_factory=self._socket_factory, ) - for sockopt in self._tcp_sockopts: - sock.setsockopt(*sockopt) connection = await self._loop.create_connection( *args, **kwargs, sock=sock ) @@ -1331,13 +1338,13 @@ async def _start_tls_connection( def _convert_hosts_to_addr_infos( self, hosts: List[ResolveResult] - ) -> List[aiohappyeyeballs.AddrInfoType]: + ) -> List[AddrInfoType]: """Converts the list of hosts to a list of addr_infos. The list of hosts is the result of a DNS lookup. The list of addr_infos is the result of a call to `socket.getaddrinfo()`. """ - addr_infos: List[aiohappyeyeballs.AddrInfoType] = [] + addr_infos: List[AddrInfoType] = [] for hinfo in hosts: host = hinfo["host"] is_ipv6 = ":" in host diff --git a/docs/client_advanced.rst b/docs/client_advanced.rst index eeb0ee98574..1116e0bdc45 100644 --- a/docs/client_advanced.rst +++ b/docs/client_advanced.rst @@ -461,19 +461,26 @@ If your HTTP server uses UNIX domain sockets you can use session = aiohttp.ClientSession(connector=conn) -Setting socket options +Custom socket creation ^^^^^^^^^^^^^^^^^^^^^^ -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:: +If the default socket is insufficient for your use case, pass an optional +`socket_factory` to the :class:`~aiohttp.TCPConnector`, which implements +`SocketFactoryType`. This will be used to create all sockets for the +lifetime of the class object. For example, we may want to change the +conditions under which we consider a connection dead. The following would +make all sockets respect 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) ]) + def socket_factory(addr_info): + family, type_, proto, _, _, _ = addr_info + sock = socket.socket(family=family, type=type_, proto=proto) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7200) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 9) + return sock + conn = aiohttp.TCPConnector(socket_factory=socket_factory) Named pipes in Windows diff --git a/docs/client_reference.rst b/docs/client_reference.rst index 1e49b014007..42b45e589ff 100644 --- a/docs/client_reference.rst +++ b/docs/client_reference.rst @@ -1138,6 +1138,34 @@ is controlled by *force_close* constructor's parameter). overridden in subclasses. +.. autodata:: AddrInfoType + +.. note:: + + Refer to :py:data:`aiohappyeyeballs.AddrInfoType` for more info. + +.. warning:: + + Be sure to use ``aiohttp.AddrInfoType`` rather than + ``aiohappyeyeballs.AddrInfoType`` to avoid import breakage, as + it is likely to be removed from ``aiohappyeyeballs`` in the + future. + + +.. autodata:: SocketFactoryType + +.. note:: + + Refer to :py:data:`aiohappyeyeballs.SocketFactoryType` for more info. + +.. warning:: + + Be sure to use ``aiohttp.SocketFactoryType`` rather than + ``aiohappyeyeballs.SocketFactoryType`` to avoid import breakage, + as it is likely to be removed from ``aiohappyeyeballs`` in the + future. + + .. class:: TCPConnector(*, ssl=True, verify_ssl=True, fingerprint=None, \ use_dns_cache=True, ttl_dns_cache=10, \ family=0, ssl_context=None, local_addr=None, \ @@ -1145,7 +1173,7 @@ is controlled by *force_close* constructor's parameter). 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, \ - tcp_sockopts=[]) + socket_factory=None) Connector for working with *HTTP* and *HTTPS* via *TCP* sockets. @@ -1266,9 +1294,9 @@ 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``. + :param :py:data:``SocketFactoryType`` socket_factory: This function takes an + :py:data:``AddrInfoType`` and is used in lieu of ``socket.socket()`` when + creating TCP connections. .. versionadded:: 3.12 diff --git a/docs/conf.py b/docs/conf.py index f60c8ffcf8c..dcab6acf247 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,6 +54,7 @@ # ones. extensions = [ # stdlib-party extensions: + "sphinx.ext.autodoc", "sphinx.ext.extlinks", "sphinx.ext.graphviz", "sphinx.ext.intersphinx", @@ -83,6 +84,7 @@ "aiohttpsession": ("https://aiohttp-session.readthedocs.io/en/stable/", None), "aiohttpdemos": ("https://aiohttp-demos.readthedocs.io/en/latest/", None), "aiojobs": ("https://aiojobs.readthedocs.io/en/stable/", None), + "aiohappyeyeballs": ("https://aiohappyeyeballs.readthedocs.io/en/stable/", None), } # Add any paths that contain templates here, relative to this directory. @@ -441,6 +443,7 @@ ("py:exc", "HTTPMethodNotAllowed"), # undocumented ("py:class", "HTTPMethodNotAllowed"), # undocumented ("py:class", "HTTPUnavailableForLegalReasons"), # undocumented + ("py:class", "socket.SocketKind"), # undocumented ] # -- Options for towncrier_draft extension ----------------------------------- diff --git a/requirements/runtime-deps.in b/requirements/runtime-deps.in index 50c6e41f9e4..425abdc85f6 100644 --- a/requirements/runtime-deps.in +++ b/requirements/runtime-deps.in @@ -1,7 +1,7 @@ # Extracted from `setup.cfg` via `make sync-direct-runtime-deps` aiodns >= 3.2.0; sys_platform=="linux" or sys_platform=="darwin" -aiohappyeyeballs >= 2.3.0 +aiohappyeyeballs >= 2.5.0 aiosignal >= 1.1.2 async-timeout >= 4.0, < 6.0 ; python_version < "3.11" attrs >= 17.3.0 diff --git a/setup.cfg b/setup.cfg index a2b9e3b29e1..9da34e0b5ce 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,7 +51,7 @@ zip_safe = False include_package_data = True install_requires = - aiohappyeyeballs >= 2.3.0 + aiohappyeyeballs >= 2.5.0 aiosignal >= 1.1.2 async-timeout >= 4.0, < 6.0 ; python_version < "3.11" attrs >= 17.3.0 diff --git a/tests/test_connector.py b/tests/test_connector.py index 2aaa50985a1..f148fdf0bbe 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -10,11 +10,20 @@ from collections import defaultdict, deque from concurrent import futures from contextlib import closing, suppress -from typing import Any, DefaultDict, Deque, List, Literal, Optional, Sequence, Tuple +from typing import ( + Any, + Callable, + DefaultDict, + Deque, + List, + Literal, + Optional, + Sequence, + Tuple, +) from unittest import mock import pytest -from aiohappyeyeballs import AddrInfoType from pytest_mock import MockerFixture from yarl import URL @@ -26,6 +35,7 @@ from aiohttp.connector import ( _SSL_CONTEXT_UNVERIFIED, _SSL_CONTEXT_VERIFIED, + AddrInfoType, Connection, TCPConnector, _DNSCacheTable, @@ -3663,27 +3673,48 @@ def test_connect() -> Literal[True]: assert raw_response_list == [True, True] -async def test_tcp_connector_setsockopts( +async def test_tcp_connector_socket_factory( 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) + """Check that socket factory is called""" + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + start_connection.return_value = s + + local_addr = None + socket_factory: Callable[[AddrInfoType], socket.socket] = lambda _: s + happy_eyeballs_delay = 0.123 + interleave = 3 + conn = aiohttp.TCPConnector( + interleave=interleave, + local_addr=local_addr, + happy_eyeballs_delay=happy_eyeballs_delay, + socket_factory=socket_factory, + ) + with mock.patch.object( + conn._loop, + "create_connection", + autospec=True, + spec_set=True, + return_value=(mock.Mock(), mock.Mock()), + ): + host = "127.0.0.1" + port = 443 + req = ClientRequest("GET", URL(f"https://{host}:{port}"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): - assert s.getsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT) == 2 - - await conn.close() + pass + await conn.close() + + start_connection.assert_called_with( + addr_infos=[ + (socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, "", (host, port)) + ], + local_addr_infos=local_addr, + happy_eyeballs_delay=happy_eyeballs_delay, + interleave=interleave, + loop=loop, + socket_factory=socket_factory, + ) def test_default_ssl_context_creation_without_ssl() -> None: From 4005080efe8b8f42c0eb367d3edc4086b9b127ed Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 22:49:25 +0000 Subject: [PATCH 35/43] [PR #10564/a59e74b7 backport][3.11] Log offending websocket client address when no protocols overlap (#10575) **This is a backport of PR #10564 as merged into master (a59e74b7b504375bc0ac3daf1dc1306d5d056d28).** ## What do these changes do? Logs the remote address of a WebSocket client that has no overlapping protocols ## Are there changes in behavior for the user? Which client has the problem should be a bit more discoverable ## Is it a substantial burden for the maintainers to support this? no ## Related issue number closes #10563 Co-authored-by: J. Nick Koston --- CHANGES/10564.feature.rst | 1 + aiohttp/web_ws.py | 3 ++- tests/test_websocket_handshake.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10564.feature.rst diff --git a/CHANGES/10564.feature.rst b/CHANGES/10564.feature.rst new file mode 100644 index 00000000000..24e2ecad76d --- /dev/null +++ b/CHANGES/10564.feature.rst @@ -0,0 +1 @@ +Improved logging on non-overlapping WebSocket client protocols to include the remote address -- by :user:`bdraco`. diff --git a/aiohttp/web_ws.py b/aiohttp/web_ws.py index a448bca101e..439b8049987 100644 --- a/aiohttp/web_ws.py +++ b/aiohttp/web_ws.py @@ -252,7 +252,8 @@ def _handshake( else: # No overlap found: Return no protocol as per spec ws_logger.warning( - "Client protocols %r don’t overlap server-known ones %r", + "%s: Client protocols %r don’t overlap server-known ones %r", + request.remote, req_protocols, self._protocols, ) diff --git a/tests/test_websocket_handshake.py b/tests/test_websocket_handshake.py index bbfa1d9260d..53d5d9152bb 100644 --- a/tests/test_websocket_handshake.py +++ b/tests/test_websocket_handshake.py @@ -174,7 +174,7 @@ async def test_handshake_protocol_unsupported(caplog) -> None: assert ( caplog.records[-1].msg - == "Client protocols %r don’t overlap server-known ones %r" + == "%s: Client protocols %r don’t overlap server-known ones %r" ) assert ws.ws_protocol is None From 70036a9557cc52cb80d660219913921636145246 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 23:09:38 +0000 Subject: [PATCH 36/43] [PR #10564/a59e74b7 backport][3.12] Log offending websocket client address when no protocols overlap (#10576) **This is a backport of PR #10564 as merged into master (a59e74b7b504375bc0ac3daf1dc1306d5d056d28).** ## What do these changes do? Logs the remote address of a WebSocket client that has no overlapping protocols ## Are there changes in behavior for the user? Which client has the problem should be a bit more discoverable ## Is it a substantial burden for the maintainers to support this? no ## Related issue number closes #10563 Co-authored-by: J. Nick Koston --- CHANGES/10564.feature.rst | 1 + aiohttp/web_ws.py | 3 ++- tests/test_websocket_handshake.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10564.feature.rst diff --git a/CHANGES/10564.feature.rst b/CHANGES/10564.feature.rst new file mode 100644 index 00000000000..24e2ecad76d --- /dev/null +++ b/CHANGES/10564.feature.rst @@ -0,0 +1 @@ +Improved logging on non-overlapping WebSocket client protocols to include the remote address -- by :user:`bdraco`. diff --git a/aiohttp/web_ws.py b/aiohttp/web_ws.py index a448bca101e..439b8049987 100644 --- a/aiohttp/web_ws.py +++ b/aiohttp/web_ws.py @@ -252,7 +252,8 @@ def _handshake( else: # No overlap found: Return no protocol as per spec ws_logger.warning( - "Client protocols %r don’t overlap server-known ones %r", + "%s: Client protocols %r don’t overlap server-known ones %r", + request.remote, req_protocols, self._protocols, ) diff --git a/tests/test_websocket_handshake.py b/tests/test_websocket_handshake.py index bbfa1d9260d..53d5d9152bb 100644 --- a/tests/test_websocket_handshake.py +++ b/tests/test_websocket_handshake.py @@ -174,7 +174,7 @@ async def test_handshake_protocol_unsupported(caplog) -> None: assert ( caplog.records[-1].msg - == "Client protocols %r don’t overlap server-known ones %r" + == "%s: Client protocols %r don’t overlap server-known ones %r" ) assert ws.ws_protocol is None From e1d2d77cc678e81f7ab7dc687edf8dd7add3ef0b Mon Sep 17 00:00:00 2001 From: Max Bachmann Date: Mon, 17 Mar 2025 00:12:09 +0100 Subject: [PATCH 37/43] only use `AI_ADDRCONFIG` when supported by getaddrinfo (#10542) The fallback implementation for getaddrinfo in CPython doesn't support `AI_ADDRCONFIG` and currently fails with a bad flags error. This changes the implementation to only set the flag if it's part of `AI_MASK`. Since `AI_MASK` isn't necessarily available either this has to be checked first. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston --- CHANGES/10542.bugfix | 1 + aiohttp/resolver.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10542.bugfix diff --git a/CHANGES/10542.bugfix b/CHANGES/10542.bugfix new file mode 100644 index 00000000000..fc3192308ad --- /dev/null +++ b/CHANGES/10542.bugfix @@ -0,0 +1 @@ +Fixed DNS resolution on platforms that don't support ``socket.AI_ADDRCONFIG`` -- by :user:`maxbachmann`. diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 9528cfe48da..d99970f3952 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -18,6 +18,9 @@ _NUMERIC_SOCKET_FLAGS = socket.AI_NUMERICHOST | socket.AI_NUMERICSERV _NAME_SOCKET_FLAGS = socket.NI_NUMERICHOST | socket.NI_NUMERICSERV +_AI_ADDRCONFIG = socket.AI_ADDRCONFIG +if hasattr(socket, "AI_MASK"): + _AI_ADDRCONFIG &= socket.AI_MASK class ThreadedResolver(AbstractResolver): @@ -38,7 +41,7 @@ async def resolve( port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) hosts: List[ResolveResult] = [] @@ -96,7 +99,7 @@ async def resolve( port=port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) except aiodns.error.DNSError as exc: msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" From 3c60cd220a8a393e5ab7cff1d39087ca77639166 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 16 Mar 2025 13:23:43 -1000 Subject: [PATCH 38/43] Parametrize leak tests (#10577) Small cleanup to the leak tests https://github.com/aio-libs/aiohttp/pull/10569#discussion_r1997747632 --- tests/test_leaks.py | 47 ++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tests/test_leaks.py b/tests/test_leaks.py index f527ce18cae..07b506bdb99 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -9,34 +9,29 @@ @pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_client_response_does_not_leak_on_server_disconnected_error() -> None: - """Test that ClientResponse is collected after server disconnects. - - https://github.com/aio-libs/aiohttp/issues/10535 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_client_response_leak.py" - ) - - with subprocess.Popen( - [sys.executable, "-u", str(leak_test_script)], - stdout=subprocess.PIPE, - ) as proc: - assert proc.wait() == 0, "ClientResponse leaked" - - -@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_request_does_not_leak_when_request_handler_raises() -> None: - """Test that the Request object is collected when the handler raises. - - https://github.com/aio-libs/aiohttp/issues/10548 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_request_leak.py" - ) +@pytest.mark.parametrize( + ("script", "message"), + [ + ( + # Test that ClientResponse is collected after server disconnects. + # https://github.com/aio-libs/aiohttp/issues/10535 + "check_for_client_response_leak.py", + "ClientResponse leaked", + ), + ( + # Test that Request object is collected when the handler raises. + # https://github.com/aio-libs/aiohttp/issues/10548 + "check_for_request_leak.py", + "Request leaked", + ), + ], +) +def test_leak(script: str, message: str) -> None: + """Run isolated leak test script and check for leaks.""" + leak_test_script = pathlib.Path(__file__).parent.joinpath("isolated", script) with subprocess.Popen( [sys.executable, "-u", str(leak_test_script)], stdout=subprocess.PIPE, ) as proc: - assert proc.wait() == 0, "Request leaked" + assert proc.wait() == 0, message From 9396ef1547eb6908cc5212bb8768a9a1eae627f8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 23:31:18 +0000 Subject: [PATCH 39/43] [PR #10542/e1d2d77c backport][3.11] only use `AI_ADDRCONFIG` when supported by getaddrinfo (#10578) --- CHANGES/10542.bugfix | 1 + aiohttp/resolver.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10542.bugfix diff --git a/CHANGES/10542.bugfix b/CHANGES/10542.bugfix new file mode 100644 index 00000000000..fc3192308ad --- /dev/null +++ b/CHANGES/10542.bugfix @@ -0,0 +1 @@ +Fixed DNS resolution on platforms that don't support ``socket.AI_ADDRCONFIG`` -- by :user:`maxbachmann`. diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 9c744514fae..e14179cc8a2 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -18,6 +18,9 @@ _NUMERIC_SOCKET_FLAGS = socket.AI_NUMERICHOST | socket.AI_NUMERICSERV _NAME_SOCKET_FLAGS = socket.NI_NUMERICHOST | socket.NI_NUMERICSERV +_AI_ADDRCONFIG = socket.AI_ADDRCONFIG +if hasattr(socket, "AI_MASK"): + _AI_ADDRCONFIG &= socket.AI_MASK class ThreadedResolver(AbstractResolver): @@ -38,7 +41,7 @@ async def resolve( port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) hosts: List[ResolveResult] = [] @@ -105,7 +108,7 @@ async def resolve( port=port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) except aiodns.error.DNSError as exc: msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" From 666523b0fc6d6b19b4bf39058f04148ebbf12002 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 23:51:44 +0000 Subject: [PATCH 40/43] [PR #10542/e1d2d77c backport][3.12] only use `AI_ADDRCONFIG` when supported by getaddrinfo (#10579) --- CHANGES/10542.bugfix | 1 + aiohttp/resolver.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10542.bugfix diff --git a/CHANGES/10542.bugfix b/CHANGES/10542.bugfix new file mode 100644 index 00000000000..fc3192308ad --- /dev/null +++ b/CHANGES/10542.bugfix @@ -0,0 +1 @@ +Fixed DNS resolution on platforms that don't support ``socket.AI_ADDRCONFIG`` -- by :user:`maxbachmann`. diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 9c744514fae..e14179cc8a2 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -18,6 +18,9 @@ _NUMERIC_SOCKET_FLAGS = socket.AI_NUMERICHOST | socket.AI_NUMERICSERV _NAME_SOCKET_FLAGS = socket.NI_NUMERICHOST | socket.NI_NUMERICSERV +_AI_ADDRCONFIG = socket.AI_ADDRCONFIG +if hasattr(socket, "AI_MASK"): + _AI_ADDRCONFIG &= socket.AI_MASK class ThreadedResolver(AbstractResolver): @@ -38,7 +41,7 @@ async def resolve( port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) hosts: List[ResolveResult] = [] @@ -105,7 +108,7 @@ async def resolve( port=port, type=socket.SOCK_STREAM, family=family, - flags=socket.AI_ADDRCONFIG, + flags=_AI_ADDRCONFIG, ) except aiodns.error.DNSError as exc: msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" From c6fedfa1b4c8e942ae7bf1cbad572c9a6a48052a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 13:56:29 -1000 Subject: [PATCH 41/43] [PR #10577/3c60cd22 backport][3.12] Parametrize leak tests (#10581) **This is a backport of PR #10577 as merged into master (3c60cd220a8a393e5ab7cff1d39087ca77639166).** Small cleanup to the leak tests https://github.com/aio-libs/aiohttp/pull/10569#discussion_r1997747632 Co-authored-by: J. Nick Koston --- tests/test_leaks.py | 47 ++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tests/test_leaks.py b/tests/test_leaks.py index f527ce18cae..07b506bdb99 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -9,34 +9,29 @@ @pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_client_response_does_not_leak_on_server_disconnected_error() -> None: - """Test that ClientResponse is collected after server disconnects. - - https://github.com/aio-libs/aiohttp/issues/10535 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_client_response_leak.py" - ) - - with subprocess.Popen( - [sys.executable, "-u", str(leak_test_script)], - stdout=subprocess.PIPE, - ) as proc: - assert proc.wait() == 0, "ClientResponse leaked" - - -@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_request_does_not_leak_when_request_handler_raises() -> None: - """Test that the Request object is collected when the handler raises. - - https://github.com/aio-libs/aiohttp/issues/10548 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_request_leak.py" - ) +@pytest.mark.parametrize( + ("script", "message"), + [ + ( + # Test that ClientResponse is collected after server disconnects. + # https://github.com/aio-libs/aiohttp/issues/10535 + "check_for_client_response_leak.py", + "ClientResponse leaked", + ), + ( + # Test that Request object is collected when the handler raises. + # https://github.com/aio-libs/aiohttp/issues/10548 + "check_for_request_leak.py", + "Request leaked", + ), + ], +) +def test_leak(script: str, message: str) -> None: + """Run isolated leak test script and check for leaks.""" + leak_test_script = pathlib.Path(__file__).parent.joinpath("isolated", script) with subprocess.Popen( [sys.executable, "-u", str(leak_test_script)], stdout=subprocess.PIPE, ) as proc: - assert proc.wait() == 0, "Request leaked" + assert proc.wait() == 0, message From d40e2270f96eae7ae4bfea9ced14062694ecfdc3 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 00:01:29 +0000 Subject: [PATCH 42/43] [PR #10577/3c60cd22 backport][3.11] Parametrize leak tests (#10580) **This is a backport of PR #10577 as merged into master (3c60cd220a8a393e5ab7cff1d39087ca77639166).** Small cleanup to the leak tests https://github.com/aio-libs/aiohttp/pull/10569#discussion_r1997747632 Co-authored-by: J. Nick Koston --- tests/test_leaks.py | 47 ++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tests/test_leaks.py b/tests/test_leaks.py index f527ce18cae..07b506bdb99 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -9,34 +9,29 @@ @pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_client_response_does_not_leak_on_server_disconnected_error() -> None: - """Test that ClientResponse is collected after server disconnects. - - https://github.com/aio-libs/aiohttp/issues/10535 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_client_response_leak.py" - ) - - with subprocess.Popen( - [sys.executable, "-u", str(leak_test_script)], - stdout=subprocess.PIPE, - ) as proc: - assert proc.wait() == 0, "ClientResponse leaked" - - -@pytest.mark.skipif(IS_PYPY, reason="gc.DEBUG_LEAK not available on PyPy") -def test_request_does_not_leak_when_request_handler_raises() -> None: - """Test that the Request object is collected when the handler raises. - - https://github.com/aio-libs/aiohttp/issues/10548 - """ - leak_test_script = pathlib.Path(__file__).parent.joinpath( - "isolated", "check_for_request_leak.py" - ) +@pytest.mark.parametrize( + ("script", "message"), + [ + ( + # Test that ClientResponse is collected after server disconnects. + # https://github.com/aio-libs/aiohttp/issues/10535 + "check_for_client_response_leak.py", + "ClientResponse leaked", + ), + ( + # Test that Request object is collected when the handler raises. + # https://github.com/aio-libs/aiohttp/issues/10548 + "check_for_request_leak.py", + "Request leaked", + ), + ], +) +def test_leak(script: str, message: str) -> None: + """Run isolated leak test script and check for leaks.""" + leak_test_script = pathlib.Path(__file__).parent.joinpath("isolated", script) with subprocess.Popen( [sys.executable, "-u", str(leak_test_script)], stdout=subprocess.PIPE, ) as proc: - assert proc.wait() == 0, "Request leaked" + assert proc.wait() == 0, message From 1a48a62fbbd4920a154451b99d90a2589c441512 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 16 Mar 2025 14:46:05 -1000 Subject: [PATCH 43/43] Release 3.11.14 (#10582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Screenshot 2025-03-16 at 2 32 10 PM --- CHANGES.rst | 77 +++++++++++++++++++++++++++++++++++++++ CHANGES/10529.bugfix.rst | 2 - CHANGES/10542.bugfix | 1 - CHANGES/10551.bugfix.rst | 1 - CHANGES/10552.misc.rst | 1 - CHANGES/10556.bugfix.rst | 3 -- CHANGES/10564.feature.rst | 1 - CHANGES/10569.bugfix.rst | 1 - aiohttp/__init__.py | 2 +- 9 files changed, 78 insertions(+), 11 deletions(-) delete mode 100644 CHANGES/10529.bugfix.rst delete mode 100644 CHANGES/10542.bugfix delete mode 100644 CHANGES/10551.bugfix.rst delete mode 100644 CHANGES/10552.misc.rst delete mode 100644 CHANGES/10556.bugfix.rst delete mode 100644 CHANGES/10564.feature.rst delete mode 100644 CHANGES/10569.bugfix.rst diff --git a/CHANGES.rst b/CHANGES.rst index 39c45196c26..3c8c12b8d95 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,83 @@ .. towncrier release notes start +3.11.14 (2025-03-16) +==================== + +Bug fixes +--------- + +- Fixed an issue where dns queries were delayed indefinitely when an exception occurred in a ``trace.send_dns_cache_miss`` + -- by :user:`logioniz`. + + + *Related issues and pull requests on GitHub:* + :issue:`10529`. + + + +- Fixed DNS resolution on platforms that don't support ``socket.AI_ADDRCONFIG`` -- by :user:`maxbachmann`. + + + *Related issues and pull requests on GitHub:* + :issue:`10542`. + + + +- The connector now raises :exc:`aiohttp.ClientConnectionError` instead of :exc:`OSError` when failing to explicitly close the socket after :py:meth:`asyncio.loop.create_connection` fails -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`10551`. + + + +- Break cyclic references at connection close when there was a traceback -- by :user:`bdraco`. + + Special thanks to :user:`availov` for reporting the issue. + + + *Related issues and pull requests on GitHub:* + :issue:`10556`. + + + +- Break cyclic references when there is an exception handling a request -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`10569`. + + + + +Features +-------- + +- Improved logging on non-overlapping WebSocket client protocols to include the remote address -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`10564`. + + + + +Miscellaneous internal changes +------------------------------ + +- Improved performance of parsing content types by adding a cache in the same manner currently done with mime types -- by :user:`bdraco`. + + + *Related issues and pull requests on GitHub:* + :issue:`10552`. + + + + +---- + + 3.11.13 (2025-02-24) ==================== diff --git a/CHANGES/10529.bugfix.rst b/CHANGES/10529.bugfix.rst deleted file mode 100644 index d6714ffd043..00000000000 --- a/CHANGES/10529.bugfix.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed an issue where dns queries were delayed indefinitely when an exception occurred in a ``trace.send_dns_cache_miss`` --- by :user:`logioniz`. diff --git a/CHANGES/10542.bugfix b/CHANGES/10542.bugfix deleted file mode 100644 index fc3192308ad..00000000000 --- a/CHANGES/10542.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed DNS resolution on platforms that don't support ``socket.AI_ADDRCONFIG`` -- by :user:`maxbachmann`. diff --git a/CHANGES/10551.bugfix.rst b/CHANGES/10551.bugfix.rst deleted file mode 100644 index 8f3eb24d6ae..00000000000 --- a/CHANGES/10551.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -The connector now raises :exc:`aiohttp.ClientConnectionError` instead of :exc:`OSError` when failing to explicitly close the socket after :py:meth:`asyncio.loop.create_connection` fails -- by :user:`bdraco`. diff --git a/CHANGES/10552.misc.rst b/CHANGES/10552.misc.rst deleted file mode 100644 index 6755cbf7396..00000000000 --- a/CHANGES/10552.misc.rst +++ /dev/null @@ -1 +0,0 @@ -Improved performance of parsing content types by adding a cache in the same manner currently done with mime types -- by :user:`bdraco`. diff --git a/CHANGES/10556.bugfix.rst b/CHANGES/10556.bugfix.rst deleted file mode 100644 index aad4eccbe48..00000000000 --- a/CHANGES/10556.bugfix.rst +++ /dev/null @@ -1,3 +0,0 @@ -Break cyclic references at connection close when there was a traceback -- by :user:`bdraco`. - -Special thanks to :user:`availov` for reporting the issue. diff --git a/CHANGES/10564.feature.rst b/CHANGES/10564.feature.rst deleted file mode 100644 index 24e2ecad76d..00000000000 --- a/CHANGES/10564.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Improved logging on non-overlapping WebSocket client protocols to include the remote address -- by :user:`bdraco`. diff --git a/CHANGES/10569.bugfix.rst b/CHANGES/10569.bugfix.rst deleted file mode 100644 index 7d817e867d4..00000000000 --- a/CHANGES/10569.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Break cyclic references when there is an exception handling a request -- by :user:`bdraco`. diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 96eced5960d..0628433d35b 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -1,4 +1,4 @@ -__version__ = "3.11.14.dev0" +__version__ = "3.11.14" from typing import TYPE_CHECKING, Tuple