summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Ożarowski <piotr@debian.org>2025-04-05 14:44:31 +0200
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2025-04-13 16:44:19 +0000
commit04a71ac1321e4607c7d0966bff7539fd65270dae (patch)
tree058817d69156f746d899203bf4f5799bb3321aa6
parent69a6f8ee84fe67115d0c2a9cb73c15baf0c2edc2 (diff)
parent3fc943c06bff7a459a7e2946b3b919081677b04c (diff)
Imported using git-ubuntu import.
-rw-r--r--CHANGES.rst27
-rw-r--r--PKG-INFO2
-rw-r--r--aiohttp.egg-info/PKG-INFO2
-rw-r--r--aiohttp/__init__.py2
-rw-r--r--aiohttp/pytest_plugin.py6
-rw-r--r--aiohttp/web_response.py4
-rw-r--r--aiohttp/web_urldispatcher.py8
-rw-r--r--aiohttp/worker.py5
-rw-r--r--debian/changelog6
-rw-r--r--tests/test_client_ws_functional.py3
-rw-r--r--tests/test_helpers.py1
-rw-r--r--tests/test_web_response.py14
-rw-r--r--tests/test_web_server.py3
13 files changed, 64 insertions, 19 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index c2654b9..00d728e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -10,6 +10,33 @@
.. towncrier release notes start
+3.11.16 (2025-04-01)
+====================
+
+Bug fixes
+---------
+
+- Replaced deprecated ``asyncio.iscoroutinefunction`` with its counterpart from ``inspect``
+ -- by :user:`layday`.
+
+
+ *Related issues and pull requests on GitHub:*
+ :issue:`10634`.
+
+
+
+- Fixed :class:`multidict.CIMultiDict` being mutated when passed to :class:`aiohttp.web.Response` -- by :user:`bdraco`.
+
+
+ *Related issues and pull requests on GitHub:*
+ :issue:`10672`.
+
+
+
+
+----
+
+
3.11.15 (2025-03-31)
====================
diff --git a/PKG-INFO b/PKG-INFO
index 55bbb90..78bb74b 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: aiohttp
-Version: 3.11.15
+Version: 3.11.16
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Maintainer: aiohttp team <team@aiohttp.org>
diff --git a/aiohttp.egg-info/PKG-INFO b/aiohttp.egg-info/PKG-INFO
index 55bbb90..78bb74b 100644
--- a/aiohttp.egg-info/PKG-INFO
+++ b/aiohttp.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: aiohttp
-Version: 3.11.15
+Version: 3.11.16
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Maintainer: aiohttp team <team@aiohttp.org>
diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py
index aba86dc..93b06c7 100644
--- a/aiohttp/__init__.py
+++ b/aiohttp/__init__.py
@@ -1,4 +1,4 @@
-__version__ = "3.11.15"
+__version__ = "3.11.16"
from typing import TYPE_CHECKING, Tuple
diff --git a/aiohttp/pytest_plugin.py b/aiohttp/pytest_plugin.py
index 7ce60fa..21d6ea7 100644
--- a/aiohttp/pytest_plugin.py
+++ b/aiohttp/pytest_plugin.py
@@ -98,7 +98,7 @@ def pytest_fixture_setup(fixturedef): # type: ignore[no-untyped-def]
if inspect.isasyncgenfunction(func):
# async generator fixture
is_async_gen = True
- elif asyncio.iscoroutinefunction(func):
+ elif inspect.iscoroutinefunction(func):
# regular async fixture
is_async_gen = False
else:
@@ -200,14 +200,14 @@ def _passthrough_loop_context(loop, fast=False): # type: ignore[no-untyped-def]
def pytest_pycollect_makeitem(collector, name, obj): # type: ignore[no-untyped-def]
"""Fix pytest collecting for coroutines."""
- if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj):
+ if collector.funcnamefilter(name) and inspect.iscoroutinefunction(obj):
return list(collector._genfunctions(name, obj))
def pytest_pyfunc_call(pyfuncitem): # type: ignore[no-untyped-def]
"""Run coroutines in an event loop instead of a normal function call."""
fast = pyfuncitem.config.getoption("--aiohttp-fast")
- if asyncio.iscoroutinefunction(pyfuncitem.function):
+ if inspect.iscoroutinefunction(pyfuncitem.function):
existing_loop = pyfuncitem.funcargs.get(
"proactor_loop"
) or pyfuncitem.funcargs.get("loop", None)
diff --git a/aiohttp/web_response.py b/aiohttp/web_response.py
index e498a90..367ac6e 100644
--- a/aiohttp/web_response.py
+++ b/aiohttp/web_response.py
@@ -629,10 +629,8 @@ class Response(StreamResponse):
if headers is None:
real_headers: CIMultiDict[str] = CIMultiDict()
- elif not isinstance(headers, CIMultiDict):
- real_headers = CIMultiDict(headers)
else:
- real_headers = headers # = cast('CIMultiDict[str]', headers)
+ real_headers = CIMultiDict(headers)
if content_type is not None and "charset" in content_type:
raise ValueError("charset must not be in content_type argument")
diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py
index 6443c50..28ae251 100644
--- a/aiohttp/web_urldispatcher.py
+++ b/aiohttp/web_urldispatcher.py
@@ -180,8 +180,8 @@ class AbstractRoute(abc.ABC):
if expect_handler is None:
expect_handler = _default_expect_handler
- assert asyncio.iscoroutinefunction(
- expect_handler
+ assert inspect.iscoroutinefunction(expect_handler) or (
+ sys.version_info < (3, 14) and asyncio.iscoroutinefunction(expect_handler)
), f"Coroutine is expected, got {expect_handler!r}"
method = method.upper()
@@ -189,7 +189,9 @@ class AbstractRoute(abc.ABC):
raise ValueError(f"{method} is not allowed HTTP method")
assert callable(handler), handler
- if asyncio.iscoroutinefunction(handler):
+ if inspect.iscoroutinefunction(handler) or (
+ sys.version_info < (3, 14) and asyncio.iscoroutinefunction(handler)
+ ):
pass
elif inspect.isgeneratorfunction(handler):
warnings.warn(
diff --git a/aiohttp/worker.py b/aiohttp/worker.py
index 8ed121a..f7281bf 100644
--- a/aiohttp/worker.py
+++ b/aiohttp/worker.py
@@ -1,6 +1,7 @@
"""Async gunicorn worker for aiohttp.web"""
import asyncio
+import inspect
import os
import re
import signal
@@ -71,7 +72,9 @@ class GunicornWebWorker(base.Worker): # type: ignore[misc,no-any-unimported]
runner = None
if isinstance(self.wsgi, Application):
app = self.wsgi
- elif asyncio.iscoroutinefunction(self.wsgi):
+ elif inspect.iscoroutinefunction(self.wsgi) or (
+ sys.version_info < (3, 14) and asyncio.iscoroutinefunction(self.wsgi)
+ ):
wsgi = await self.wsgi()
if isinstance(wsgi, web.AppRunner):
runner = wsgi
diff --git a/debian/changelog b/debian/changelog
index 7712d16..aa64486 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-aiohttp (3.11.16-1) unstable; urgency=medium
+
+ * New upstream release
+
+ -- Piotr Ożarowski <piotr@debian.org> Sat, 05 Apr 2025 14:44:31 +0200
+
python-aiohttp (3.11.15-1) unstable; urgency=medium
* Team upload.
diff --git a/tests/test_client_ws_functional.py b/tests/test_client_ws_functional.py
index 54cd5e9..0ca57ab 100644
--- a/tests/test_client_ws_functional.py
+++ b/tests/test_client_ws_functional.py
@@ -315,7 +315,6 @@ async def test_concurrent_close(aiohttp_client) -> None:
client_ws = None
async def handler(request):
- nonlocal client_ws
ws = web.WebSocketResponse()
await ws.prepare(request)
@@ -936,7 +935,7 @@ async def test_close_websocket_while_ping_inflight(
message: bytes, opcode: int, compress: Optional[int] = None
) -> None:
assert opcode == WSMsgType.PING
- nonlocal cancelled, ping_started
+ nonlocal cancelled
ping_started.set_result(None)
try:
await asyncio.sleep(1)
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index 2a83032..a343cbd 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -351,7 +351,6 @@ async def test_timer_context_timeout_does_swallow_cancellation() -> None:
ctx = helpers.TimerContext(loop)
async def task_with_timeout() -> None:
- nonlocal ctx
new_task = asyncio.current_task()
assert new_task is not None
with pytest.raises(asyncio.TimeoutError):
diff --git a/tests/test_web_response.py b/tests/test_web_response.py
index 0591426..9576916 100644
--- a/tests/test_web_response.py
+++ b/tests/test_web_response.py
@@ -10,7 +10,7 @@ from unittest import mock
import aiosignal
import pytest
-from multidict import CIMultiDict, CIMultiDictProxy
+from multidict import CIMultiDict, CIMultiDictProxy, MultiDict
from re_assert import Matches
from aiohttp import HttpVersion, HttpVersion10, HttpVersion11, hdrs
@@ -1479,3 +1479,15 @@ class TestJSONResponse:
def test_content_type_is_overrideable(self) -> None:
resp = json_response({"foo": 42}, content_type="application/vnd.json+api")
assert "application/vnd.json+api" == resp.content_type
+
+
+@pytest.mark.parametrize("loose_header_type", (MultiDict, CIMultiDict, dict))
+async def test_passing_cimultidict_to_web_response_not_mutated(
+ loose_header_type: type,
+) -> None:
+ req = make_request("GET", "/")
+ headers = loose_header_type({})
+ resp = Response(body=b"answer", headers=headers)
+ await resp.prepare(req)
+ assert resp.content_length == 6
+ assert not headers
diff --git a/tests/test_web_server.py b/tests/test_web_server.py
index 9098ef9..d2f1341 100644
--- a/tests/test_web_server.py
+++ b/tests/test_web_server.py
@@ -347,7 +347,6 @@ async def test_handler_cancellation(unused_port_socket: socket.socket) -> None:
port = sock.getsockname()[1]
async def on_request(_: web.Request) -> web.Response:
- nonlocal event
try:
await asyncio.sleep(10)
except asyncio.CancelledError:
@@ -389,7 +388,7 @@ async def test_no_handler_cancellation(unused_port_socket: socket.socket) -> Non
started = False
async def on_request(_: web.Request) -> web.Response:
- nonlocal done_event, started, timeout_event
+ nonlocal started
started = True
await asyncio.wait_for(timeout_event.wait(), timeout=5)
done_event.set()