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
[](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
[](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
[](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.

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
[](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
[](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
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
[](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
[](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
[](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
[](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
[](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
[](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
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
[](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
[](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
[](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
[](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
[](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
[](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
[](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.
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.
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
---
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