Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1bd7faa
[3.11] Increment version to 3.11.13.dev0 (#10420)
bdraco Feb 6, 2025
c4523f3
[PR #10426/fae142f5 backport][3.11] Add benchmark for streaming API i…
patchback[bot] Feb 6, 2025
655c2f3
[PR #10426/fae142f5 backport][3.12] Add benchmark for streaming API i…
patchback[bot] Feb 6, 2025
cae5b2e
[PR #10423/51daf719 backport][3.12] Disable writelines for test_write…
patchback[bot] Feb 6, 2025
a3d8bd3
[PR #10422/289259d1 backport][3.12] Add human readable error messages…
patchback[bot] Feb 6, 2025
5942b0b
[PR #10422/289259d1 backport][3.11] Add human readable error messages…
patchback[bot] Feb 6, 2025
0ed7f2f
Bump mypy from 1.11.2 to 1.15.0 (#10385)
dependabot[bot] Feb 6, 2025
cf19b04
[PR #10423/51daf719 backport][3.11] Disable writelines for test_write…
patchback[bot] Feb 7, 2025
b020505
Bump aiohappyeyeballs from 2.4.4 to 2.4.6 (#10441)
dependabot[bot] Feb 10, 2025
ba3228e
Bump pip from 25.0 to 25.0.1 (#10442)
dependabot[bot] Feb 10, 2025
ccbe9ac
Bump coverage from 7.6.10 to 7.6.11 (#10444)
dependabot[bot] Feb 10, 2025
1ea7559
[PR #10447/343c632d backport][3.12] Fix test when symlink encountered…
patchback[bot] Feb 11, 2025
094bf4e
[PR #10447/343c632d backport][3.11] Fix test when symlink encountered…
patchback[bot] Feb 11, 2025
75f7b18
Bump cython from 3.0.11 to 3.0.12 (#10452)
dependabot[bot] Feb 11, 2025
328275b
Bump virtualenv from 20.29.1 to 20.29.2 (#10453)
dependabot[bot] Feb 11, 2025
c0871b0
Bump valkey from 6.0.2 to 6.1.0 (#10460)
dependabot[bot] Feb 12, 2025
b8b7159
Bump cryptography from 44.0.0 to 44.0.1 (#10461)
dependabot[bot] Feb 12, 2025
8b39002
Bump actions/cache from 4.2.0 to 4.2.1 (#10472)
dependabot[bot] Feb 20, 2025
79c5093
[PR #10434/ed84464 backport][3.11] Fix inappropriate "break in finall…
Cycloctane Feb 20, 2025
9f933bf
[PR #10434/ed84464 backport][3.12] Fix inappropriate "break in finall…
Cycloctane Feb 20, 2025
b7187a8
[PR #10464/182198fc backport][3.11] Close the socket if there's a fai…
patchback[bot] Feb 20, 2025
a9c8841
[PR #10464/182198fc backport][3.12] Close the socket if there's a fai…
patchback[bot] Feb 20, 2025
d896b21
Bump proxy-py from 2.4.9 to 2.4.10 (#10471)
dependabot[bot] Feb 20, 2025
ae62206
Bump coverage from 7.6.11 to 7.6.12 (#10462)
dependabot[bot] Feb 20, 2025
be1159b
Bump identify from 2.6.6 to 2.6.7 (#10443)
dependabot[bot] Feb 20, 2025
af48c8d
[PR #10433/0c4b1c7 backport][3.12] Detect blocking calls in coroutine…
cbornet Feb 21, 2025
079a242
[PR #10481/60819de backport][3.12] Bump blockbuster to 1.5.22 (#10481…
cbornet Feb 21, 2025
0704705
Bump propcache from 0.2.1 to 0.3.0 (#10483)
dependabot[bot] Feb 21, 2025
1c114ac
Bump propcache from 0.2.1 to 0.3.0 (#10484)
dependabot[bot] Feb 21, 2025
e565ed5
Bump blockbuster from 1.5.21 to 1.5.22 (#10485)
dependabot[bot] Feb 21, 2025
7379a86
Expose setsockopt in TCPConnector API (#10474)
TimMenninger Feb 21, 2025
17983d3
[PR #10474/7379a866 backport][3.12] Expose setsockopt in TCPConnector…
patchback[bot] Feb 21, 2025
ca6b798
Bump identify from 2.6.7 to 2.6.8 (#10487)
dependabot[bot] Feb 24, 2025
d64535a
Bump blockbuster from 1.5.22 to 1.5.23 (#10488)
dependabot[bot] Feb 24, 2025
c8143c3
Bump identify from 2.6.7 to 2.6.8 (#10489)
dependabot[bot] Feb 24, 2025
94924a3
Bump blockbuster from 1.5.22 to 1.5.23 (#10490)
dependabot[bot] Feb 24, 2025
6f09c51
Release 3.11.13 (#10491)
bdraco Feb 24, 2025
9d9a3cc
Merge branch '3.11' into 3.12
bdraco Feb 24, 2025
14936fd
Merge branch '3.12'
bdraco Feb 24, 2025
8e8fa95
Document adjustments to the release process (#10493)
bdraco Feb 26, 2025
c738a83
Bump setuptools from 75.8.0 to 75.8.1 (#10497)
dependabot[bot] Feb 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,59 @@

.. towncrier release notes start

3.11.13 (2025-02-24)
====================

Bug fixes
---------

- Removed a break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler`
-- by :user:`Cycloctane`.


*Related issues and pull requests on GitHub:*
:issue:`10434`.



- Changed connection creation to explicitly close sockets if an exception is raised in the event loop's ``create_connection`` method -- by :user:`top-oai`.


*Related issues and pull requests on GitHub:*
:issue:`10464`.




Packaging updates and notes for downstreams
-------------------------------------------

- Fixed test ``test_write_large_payload_deflate_compression_data_in_eof_writelines`` failing with Python 3.12.9+ or 3.13.2+ -- by :user:`bdraco`.


*Related issues and pull requests on GitHub:*
:issue:`10423`.




Miscellaneous internal changes
------------------------------

- Added human-readable error messages to the exceptions for WebSocket disconnects due to PONG not being received -- by :user:`bdraco`.

Previously, the error messages were empty strings, which made it hard to determine what went wrong.


*Related issues and pull requests on GitHub:*
:issue:`10422`.




----


3.11.12 (2025-02-05)
====================

Expand Down
3 changes: 0 additions & 3 deletions CHANGES/10422.misc.rst

This file was deleted.

1 change: 0 additions & 1 deletion CHANGES/10423.packaging.rst

This file was deleted.

2 changes: 0 additions & 2 deletions CHANGES/10434.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion CHANGES/10464.bugfix.rst

This file was deleted.

2 changes: 2 additions & 0 deletions CHANGES/10474.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added ``tcp_sockopts`` to ``TCPConnector`` to allow specifying custom socket options
-- by :user:`TimMenninger`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ Thanos Lefteris
Thijs Vermeir
Thomas Forbes
Thomas Grainger
Tim Menninger
Tolga Tezel
Tomasz Trebski
Toshiaki Tanaka
Expand Down
12 changes: 12 additions & 0 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
DefaultDict,
Deque,
Dict,
Iterable,
Iterator,
List,
Literal,
Expand Down Expand Up @@ -61,6 +62,11 @@
)
from .resolver import DefaultResolver

if sys.version_info >= (3, 12):
from collections.abc import Buffer
else:
Buffer = Union[bytes, bytearray, "memoryview[int]", "memoryview[bytes]"]

if TYPE_CHECKING:
import ssl

Expand Down Expand Up @@ -820,6 +826,8 @@ class TCPConnector(BaseConnector):
the happy eyeballs algorithm, set to None.
interleave - “First Address Family Count” as defined in RFC 8305
loop - Optional event loop.
tcp_sockopts - List of tuples of sockopts applied to underlying
socket
"""

allowed_protocol_schema_set = HIGH_LEVEL_SCHEMA_SET | frozenset({"tcp"})
Expand All @@ -841,6 +849,7 @@ def __init__(
timeout_ceil_threshold: float = 5,
happy_eyeballs_delay: Optional[float] = 0.25,
interleave: Optional[int] = None,
tcp_sockopts: Iterable[Tuple[int, int, Union[int, Buffer]]] = [],
):
super().__init__(
keepalive_timeout=keepalive_timeout,
Expand Down Expand Up @@ -871,6 +880,7 @@ def __init__(
self._happy_eyeballs_delay = happy_eyeballs_delay
self._interleave = interleave
self._resolve_host_tasks: Set["asyncio.Task[List[ResolveResult]]"] = set()
self._tcp_sockopts = tcp_sockopts

def _close_immediately(self) -> List[Awaitable[object]]:
for fut in chain.from_iterable(self._throttle_dns_futures.values()):
Expand Down Expand Up @@ -1113,6 +1123,8 @@ async def _wrap_create_connection(
interleave=self._interleave,
loop=self._loop,
)
for sockopt in self._tcp_sockopts:
sock.setsockopt(*sockopt)
connection = await self._loop.create_connection(
*args, **kwargs, sock=sock
)
Expand Down
15 changes: 15 additions & 0 deletions docs/client_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,21 @@ If your HTTP server uses UNIX domain sockets you can use
session = aiohttp.ClientSession(connector=conn)


Setting socket options
^^^^^^^^^^^^^^^^^^^^^^

Socket options passed to the :class:`~aiohttp.TCPConnector` will be passed
to the underlying socket when creating a connection. For example, we may
want to change the conditions under which we consider a connection dead.
The following would change that to 9*7200 = 18 hours::

import socket

conn = aiohttp.TCPConnector(tcp_sockopts=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True),
(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7200),
(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 9) ])


Named pipes in Windows
^^^^^^^^^^^^^^^^^^^^^^

Expand Down
9 changes: 8 additions & 1 deletion docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,8 @@ is controlled by *force_close* constructor's parameter).
resolver=None, keepalive_timeout=sentinel, \
force_close=False, limit=100, limit_per_host=0, \
enable_cleanup_closed=False, timeout_ceil_threshold=5, \
happy_eyeballs_delay=0.25, interleave=None, loop=None)
happy_eyeballs_delay=0.25, interleave=None, loop=None, \
tcp_sockopts=[])

Connector for working with *HTTP* and *HTTPS* via *TCP* sockets.

Expand Down Expand Up @@ -1249,6 +1250,12 @@ is controlled by *force_close* constructor's parameter).

.. versionadded:: 3.10

:param list tcp_sockopts: options applied to the socket when a connection is
created. This should be a list of 3-tuples, each a ``(level, optname, value)``.
Each tuple is deconstructed and passed verbatim to ``<socket>.setsockopt``.

.. versionadded:: 3.12

.. attribute:: family

*TCP* socket family e.g. :data:`socket.AF_INET` or
Expand Down
8 changes: 6 additions & 2 deletions docs/contributing-admins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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``
Expand Down
2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ multidict==6.1.0
# yarl
packaging==24.2
# via gunicorn
propcache==0.2.1
propcache==0.3.0
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down
8 changes: 4 additions & 4 deletions requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11"
# valkey
babel==2.17.0
# via sphinx
blockbuster==1.5.21
blockbuster==1.5.23
# via
# -r requirements/lint.in
# -r requirements/test.in
Expand Down Expand Up @@ -86,7 +86,7 @@ gidgethub==5.3.0
# via cherry-picker
gunicorn==23.0.0
# via -r requirements/base.in
identify==2.6.7
identify==2.6.8
# via pre-commit
idna==3.6
# via
Expand Down Expand Up @@ -136,7 +136,7 @@ pluggy==1.5.0
# via pytest
pre-commit==4.1.0
# via -r requirements/lint.in
propcache==0.2.1
propcache==0.3.0
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -284,7 +284,7 @@ yarl==1.18.3
# The following packages are considered to be unsafe in a requirements file:
pip==25.0.1
# via pip-tools
setuptools==75.8.0
setuptools==75.8.1
# via
# incremental
# pip-tools
8 changes: 4 additions & 4 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async-timeout==5.0.1 ; python_version < "3.11"
# valkey
babel==2.17.0
# via sphinx
blockbuster==1.5.21
blockbuster==1.5.23
# via
# -r requirements/lint.in
# -r requirements/test.in
Expand Down Expand Up @@ -84,7 +84,7 @@ gidgethub==5.3.0
# via cherry-picker
gunicorn==23.0.0
# via -r requirements/base.in
identify==2.6.7
identify==2.6.8
# via pre-commit
idna==3.6
# via
Expand Down Expand Up @@ -133,7 +133,7 @@ pluggy==1.5.0
# via pytest
pre-commit==4.1.0
# via -r requirements/lint.in
propcache==0.2.1
propcache==0.3.0
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down Expand Up @@ -275,7 +275,7 @@ yarl==1.18.3
# The following packages are considered to be unsafe in a requirements file:
pip==25.0.1
# via pip-tools
setuptools==75.8.0
setuptools==75.8.1
# via
# incremental
# pip-tools
2 changes: 1 addition & 1 deletion requirements/doc-spelling.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion requirements/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions requirements/lint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ annotated-types==0.7.0
# via pydantic
async-timeout==5.0.1
# via valkey
blockbuster==1.5.22
blockbuster==1.5.23
# via -r requirements/lint.in
cffi==1.17.1
# via
Expand All @@ -33,7 +33,7 @@ forbiddenfruit==0.1.4
# via blockbuster
freezegun==1.5.1
# via -r requirements/lint.in
identify==2.6.7
identify==2.6.8
# via pre-commit
idna==3.7
# via trustme
Expand Down
2 changes: 1 addition & 1 deletion requirements/runtime-deps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ multidict==6.1.0
# via
# -r requirements/runtime-deps.in
# yarl
propcache==0.2.1
propcache==0.3.0
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down
4 changes: 2 additions & 2 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ annotated-types==0.7.0
# via pydantic
async-timeout==5.0.1 ; python_version < "3.11"
# via -r requirements/runtime-deps.in
blockbuster==1.5.22
blockbuster==1.5.23
# via -r requirements/test.in
brotli==1.1.0 ; platform_python_implementation == "CPython"
# via -r requirements/runtime-deps.in
Expand Down Expand Up @@ -69,7 +69,7 @@ packaging==24.2
# pytest
pluggy==1.5.0
# via pytest
propcache==0.2.1
propcache==0.3.0
# via
# -r requirements/runtime-deps.in
# yarl
Expand Down
23 changes: 23 additions & 0 deletions tests/test_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3767,6 +3767,29 @@ def test_connect() -> Literal[True]:
assert raw_response_list == [True, True]


async def test_tcp_connector_setsockopts(
loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock
) -> None:
"""Check that sockopts get passed to socket"""
conn = aiohttp.TCPConnector(
tcp_sockopts=[(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2)]
)

with mock.patch.object(
conn._loop, "create_connection", autospec=True, spec_set=True
) as create_connection:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
start_connection.return_value = s
create_connection.return_value = mock.Mock(), mock.Mock()

req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop)

with closing(await conn.connect(req, [], ClientTimeout())):
assert s.getsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT) == 2

await conn.close()


def test_default_ssl_context_creation_without_ssl() -> None:
"""Verify _make_ssl_context does not raise when ssl is not available."""
with mock.patch.object(connector_module, "ssl", None):
Expand Down
Loading