diff --git a/CHANGES/11776.misc.rst b/CHANGES/11776.misc.rst new file mode 100644 index 00000000000..f35965fb651 --- /dev/null +++ b/CHANGES/11776.misc.rst @@ -0,0 +1,2 @@ +The warnings emitted when using ``str`` keys in ``web.Response``/``web.Request`` +have been removed to avoid any performance concerns when frequently using these -- by :user:`Dreamsorcerer`. diff --git a/aiohttp/web_request.py b/aiohttp/web_request.py index a7bbdaac56e..96a8977def8 100644 --- a/aiohttp/web_request.py +++ b/aiohttp/web_request.py @@ -7,7 +7,6 @@ import sys import tempfile import types -import warnings from collections.abc import Iterator, Mapping, MutableMapping from re import Pattern from types import MappingProxyType @@ -50,7 +49,6 @@ HTTPBadRequest, HTTPRequestEntityTooLarge, HTTPUnsupportedMediaType, - NotAppKeyWarning, ) from .web_response import StreamResponse @@ -118,7 +116,6 @@ class BaseRequest(MutableMapping[str | RequestKey[Any], Any], HeadersMixin): _post: MultiDictProxy[str | bytes | FileField] | None = None _read_bytes: bytes | None = None - _seen_str_keys: set[str] = set() def __init__( self, @@ -276,15 +273,6 @@ def __setitem__(self, key: RequestKey[_T], value: _T) -> None: ... def __setitem__(self, key: str, value: Any) -> None: ... def __setitem__(self, key: str | RequestKey[_T], value: Any) -> None: - if not isinstance(key, RequestKey) and key not in BaseRequest._seen_str_keys: - BaseRequest._seen_str_keys.add(key) - warnings.warn( - "It is recommended to use web.RequestKey instances for keys.\n" - + "https://docs.aiohttp.org/en/stable/web_advanced.html" - + "#request-s-storage", - category=NotAppKeyWarning, - stacklevel=2, - ) self._state[key] = value def __delitem__(self, key: str | RequestKey[_T]) -> None: diff --git a/aiohttp/web_response.py b/aiohttp/web_response.py index 0a03a8188d7..7b506716f8b 100644 --- a/aiohttp/web_response.py +++ b/aiohttp/web_response.py @@ -33,7 +33,6 @@ from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11 from .payload import Payload from .typedefs import JSONEncoder, LooseHeaders -from .web_exceptions import NotAppKeyWarning REASON_PHRASES = {http_status.value: http_status.phrase for http_status in HTTPStatus} LARGE_BODY_SIZE = 1024**2 @@ -84,7 +83,6 @@ class StreamResponse( _must_be_empty_body: bool | None = None _body_length = 0 _send_headers_immediately = True - _seen_str_keys: set[str] = set() def __init__( self, @@ -507,18 +505,6 @@ def __setitem__(self, key: ResponseKey[_T], value: _T) -> None: ... def __setitem__(self, key: str, value: Any) -> None: ... def __setitem__(self, key: str | ResponseKey[_T], value: Any) -> None: - if ( - not isinstance(key, ResponseKey) - and key not in StreamResponse._seen_str_keys - ): - StreamResponse._seen_str_keys.add(key) - warnings.warn( - "It is recommended to use web.ResponseKey instances for keys.\n" - + "https://docs.aiohttp.org/en/stable/web_advanced.html" - + "#response-s-storage", - category=NotAppKeyWarning, - stacklevel=2, - ) self._state[key] = value def __delitem__(self, key: str | ResponseKey[_T]) -> None: diff --git a/requirements/constraints.txt b/requirements/constraints.txt index c6d01bdb10c..37c1201cb2e 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -59,7 +59,7 @@ coverage==7.11.0 # pytest-cov cryptography==46.0.3 # via trustme -cython==3.1.6 +cython==3.2.2 # via -r requirements/cython.in distlib==0.4.0 # via virtualenv diff --git a/requirements/cython.txt b/requirements/cython.txt index 05f39110b33..6d9424a8755 100644 --- a/requirements/cython.txt +++ b/requirements/cython.txt @@ -4,7 +4,7 @@ # # pip-compile --allow-unsafe --output-file=requirements/cython.txt --resolver=backtracking --strip-extras requirements/cython.in # -cython==3.1.6 +cython==3.2.2 # via -r requirements/cython.in multidict==6.7.0 # via -r requirements/multidict.in diff --git a/tests/test_web_request.py b/tests/test_web_request.py index 6f295212fbc..905ba0d0ba7 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -444,7 +444,6 @@ def test_match_info() -> None: assert req._match_info is req.match_info -@pytest.mark.filterwarnings(r"ignore:.*web\.RequestKey:UserWarning") def test_request_is_mutable_mapping() -> None: req = make_mocked_request("GET", "/") assert isinstance(req, MutableMapping) @@ -453,7 +452,6 @@ def test_request_is_mutable_mapping() -> None: assert "value" == req["key"] -@pytest.mark.filterwarnings(r"ignore:.*web\.RequestKey:UserWarning") def test_request_delitem() -> None: req = make_mocked_request("GET", "/") req["key"] = "value" @@ -462,7 +460,6 @@ def test_request_delitem() -> None: assert "key" not in req -@pytest.mark.filterwarnings(r"ignore:.*web\.RequestKey:UserWarning") def test_request_len() -> None: req = make_mocked_request("GET", "/") assert len(req) == 0 @@ -470,7 +467,6 @@ def test_request_len() -> None: assert len(req) == 1 -@pytest.mark.filterwarnings(r"ignore:.*web\.RequestKey:UserWarning") def test_request_iter() -> None: req = make_mocked_request("GET", "/") req["key"] = "value" @@ -544,19 +540,6 @@ def test_requestkey_repr_annotated() -> None: ) -def test_str_key_warnings() -> None: - # Check if warnings are raised once per str key - req = make_mocked_request("GET", "/") - - with pytest.warns(UserWarning): - req["test_str_key_warnings_key_1"] = "value" - - with pytest.warns(UserWarning): - req["test_str_key_warnings_key_2"] = "value 2" - - req["test_str_key_warnings_key_1"] = "value" - - def test___repr__() -> None: req = make_mocked_request("GET", "/path/to") assert "" == repr(req) @@ -942,7 +925,6 @@ def test_remote_peername_unix() -> None: assert req.remote == "/path/to/sock" -@pytest.mark.filterwarnings(r"ignore:.*web\.RequestKey:UserWarning") def test_save_state_on_clone() -> None: req = make_mocked_request("GET", "/") req["key"] = "val" diff --git a/tests/test_web_response.py b/tests/test_web_response.py index 41136c175f4..32975f562d1 100644 --- a/tests/test_web_response.py +++ b/tests/test_web_response.py @@ -90,7 +90,6 @@ def test_stream_response_eq() -> None: assert not resp1 == resp2 -@pytest.mark.filterwarnings(r"ignore:.*web\.ResponseKey:UserWarning") def test_stream_response_is_mutable_mapping() -> None: resp = web.StreamResponse() assert isinstance(resp, collections.abc.MutableMapping) @@ -99,7 +98,6 @@ def test_stream_response_is_mutable_mapping() -> None: assert "value" == resp["key"] -@pytest.mark.filterwarnings(r"ignore:.*web\.ResponseKey:UserWarning") def test_stream_response_delitem() -> None: resp = web.StreamResponse() resp["key"] = "value" @@ -107,7 +105,6 @@ def test_stream_response_delitem() -> None: assert "key" not in resp -@pytest.mark.filterwarnings(r"ignore:.*web\.ResponseKey:UserWarning") def test_stream_response_len() -> None: resp = web.StreamResponse() assert len(resp) == 0 @@ -115,7 +112,6 @@ def test_stream_response_len() -> None: assert len(resp) == 1 -@pytest.mark.filterwarnings(r"ignore:.*web\.ResponseKey:UserWarning") def test_response_iter() -> None: resp = web.StreamResponse() resp["key"] = "value" @@ -189,19 +185,6 @@ def test_responsekey_repr_annotated() -> None: ) -def test_str_key_warnings() -> None: - # Check if warnings are raised once per str key - resp = web.StreamResponse() - - with pytest.warns(UserWarning): - resp["test_str_key_warnings_key_1"] = "value" - - with pytest.warns(UserWarning): - resp["test_str_key_warnings_key_2"] = "value 2" - - resp["test_str_key_warnings_key_1"] = "value" - - def test_content_length() -> None: resp = web.StreamResponse() assert resp.content_length is None