From 9f28a35d6dc504b2370e4cfba9811728159ddbfb Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 27 Nov 2020 11:11:22 +0200 Subject: [PATCH] Switch to external frozenlist and aiosignal libraries (#5293) --- .gitignore | 2 - CHANGES/5293.feature | 1 + aiohttp/__init__.py | 1 - aiohttp/_frozenlist.pyx | 108 ----------------- aiohttp/frozenlist.py | 72 ----------- aiohttp/frozenlist.pyi | 46 ------- aiohttp/signals.py | 34 ------ aiohttp/signals.pyi | 12 -- aiohttp/test_utils.py | 2 +- aiohttp/tracing.py | 2 +- aiohttp/web_app.py | 4 +- requirements/base.txt | 2 + setup.py | 3 +- tests/test_frozenlist.py | 231 ------------------------------------ tests/test_signals.py | 169 -------------------------- tests/test_web_response.py | 9 +- tests/test_web_websocket.py | 5 +- 17 files changed, 17 insertions(+), 686 deletions(-) create mode 100644 CHANGES/5293.feature delete mode 100644 aiohttp/_frozenlist.pyx delete mode 100644 aiohttp/frozenlist.py delete mode 100644 aiohttp/frozenlist.pyi delete mode 100644 aiohttp/signals.py delete mode 100644 aiohttp/signals.pyi delete mode 100644 tests/test_frozenlist.py delete mode 100644 tests/test_signals.py diff --git a/.gitignore b/.gitignore index 69f52e10d87..8556509c6f7 100644 --- a/.gitignore +++ b/.gitignore @@ -34,8 +34,6 @@ .vimrc .vscode aiohttp/_find_header.c -aiohttp/_frozenlist.c -aiohttp/_frozenlist.html aiohttp/_headers.html aiohttp/_headers.pxi aiohttp/_helpers.c diff --git a/CHANGES/5293.feature b/CHANGES/5293.feature new file mode 100644 index 00000000000..fced7ed5aca --- /dev/null +++ b/CHANGES/5293.feature @@ -0,0 +1 @@ +Switch to external frozenlist and aiosignal libraries. diff --git a/aiohttp/__init__.py b/aiohttp/__init__.py index 082dc58ab9c..113089ae0b9 100644 --- a/aiohttp/__init__.py +++ b/aiohttp/__init__.py @@ -77,7 +77,6 @@ DefaultResolver as DefaultResolver, ThreadedResolver as ThreadedResolver, ) -from .signals import Signal as Signal from .streams import ( EMPTY_PAYLOAD as EMPTY_PAYLOAD, DataQueue as DataQueue, diff --git a/aiohttp/_frozenlist.pyx b/aiohttp/_frozenlist.pyx deleted file mode 100644 index b1305772f4b..00000000000 --- a/aiohttp/_frozenlist.pyx +++ /dev/null @@ -1,108 +0,0 @@ -from collections.abc import MutableSequence - - -cdef class FrozenList: - - cdef readonly bint frozen - cdef list _items - - def __init__(self, items=None): - self.frozen = False - if items is not None: - items = list(items) - else: - items = [] - self._items = items - - cdef object _check_frozen(self): - if self.frozen: - raise RuntimeError("Cannot modify frozen list.") - - cdef inline object _fast_len(self): - return len(self._items) - - def freeze(self): - self.frozen = True - - def __getitem__(self, index): - return self._items[index] - - def __setitem__(self, index, value): - self._check_frozen() - self._items[index] = value - - def __delitem__(self, index): - self._check_frozen() - del self._items[index] - - def __len__(self): - return self._fast_len() - - def __iter__(self): - return self._items.__iter__() - - def __reversed__(self): - return self._items.__reversed__() - - def __richcmp__(self, other, op): - if op == 0: # < - return list(self) < other - if op == 1: # <= - return list(self) <= other - if op == 2: # == - return list(self) == other - if op == 3: # != - return list(self) != other - if op == 4: # > - return list(self) > other - if op == 5: # => - return list(self) >= other - - def insert(self, pos, item): - self._check_frozen() - self._items.insert(pos, item) - - def __contains__(self, item): - return item in self._items - - def __iadd__(self, items): - self._check_frozen() - self._items += list(items) - return self - - def index(self, item): - return self._items.index(item) - - def remove(self, item): - self._check_frozen() - self._items.remove(item) - - def clear(self): - self._check_frozen() - self._items.clear() - - def extend(self, items): - self._check_frozen() - self._items += list(items) - - def reverse(self): - self._check_frozen() - self._items.reverse() - - def pop(self, index=-1): - self._check_frozen() - return self._items.pop(index) - - def append(self, item): - self._check_frozen() - return self._items.append(item) - - def count(self, item): - return self._items.count(item) - - def __repr__(self): - return ''.format(self.frozen, - self._items) - - -MutableSequence.register(FrozenList) diff --git a/aiohttp/frozenlist.py b/aiohttp/frozenlist.py deleted file mode 100644 index 46b26108cfa..00000000000 --- a/aiohttp/frozenlist.py +++ /dev/null @@ -1,72 +0,0 @@ -from collections.abc import MutableSequence -from functools import total_ordering - -from .helpers import NO_EXTENSIONS - - -@total_ordering -class FrozenList(MutableSequence): - - __slots__ = ("_frozen", "_items") - - def __init__(self, items=None): - self._frozen = False - if items is not None: - items = list(items) - else: - items = [] - self._items = items - - @property - def frozen(self): - return self._frozen - - def freeze(self): - self._frozen = True - - def __getitem__(self, index): - return self._items[index] - - def __setitem__(self, index, value): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - self._items[index] = value - - def __delitem__(self, index): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - del self._items[index] - - def __len__(self): - return self._items.__len__() - - def __iter__(self): - return self._items.__iter__() - - def __reversed__(self): - return self._items.__reversed__() - - def __eq__(self, other): - return list(self) == other - - def __le__(self, other): - return list(self) <= other - - def insert(self, pos, item): - if self._frozen: - raise RuntimeError("Cannot modify frozen list.") - self._items.insert(pos, item) - - def __repr__(self): - return f"" - - -PyFrozenList = FrozenList - -try: - from aiohttp._frozenlist import FrozenList as CFrozenList # type: ignore - - if not NO_EXTENSIONS: - FrozenList = CFrozenList # type: ignore -except ImportError: # pragma: no cover - pass diff --git a/aiohttp/frozenlist.pyi b/aiohttp/frozenlist.pyi deleted file mode 100644 index 72ab086715b..00000000000 --- a/aiohttp/frozenlist.pyi +++ /dev/null @@ -1,46 +0,0 @@ -from typing import ( - Generic, - Iterable, - Iterator, - List, - MutableSequence, - Optional, - TypeVar, - Union, - overload, -) - -_T = TypeVar("_T") -_Arg = Union[List[_T], Iterable[_T]] - -class FrozenList(MutableSequence[_T], Generic[_T]): - def __init__(self, items: Optional[_Arg[_T]] = ...) -> None: ... - @property - def frozen(self) -> bool: ... - def freeze(self) -> None: ... - @overload - def __getitem__(self, i: int) -> _T: ... - @overload - def __getitem__(self, s: slice) -> FrozenList[_T]: ... - @overload - def __setitem__(self, i: int, o: _T) -> None: ... - @overload - def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... - @overload - def __delitem__(self, i: int) -> None: ... - @overload - def __delitem__(self, i: slice) -> None: ... - def __len__(self) -> int: ... - def __iter__(self) -> Iterator[_T]: ... - def __reversed__(self) -> Iterator[_T]: ... - def __eq__(self, other: object) -> bool: ... - def __le__(self, other: FrozenList[_T]) -> bool: ... - def __ne__(self, other: object) -> bool: ... - def __lt__(self, other: FrozenList[_T]) -> bool: ... - def __ge__(self, other: FrozenList[_T]) -> bool: ... - def __gt__(self, other: FrozenList[_T]) -> bool: ... - def insert(self, pos: int, item: _T) -> None: ... - def __repr__(self) -> str: ... - -# types for C accelerators are the same -CFrozenList = PyFrozenList = FrozenList diff --git a/aiohttp/signals.py b/aiohttp/signals.py deleted file mode 100644 index d406c02423b..00000000000 --- a/aiohttp/signals.py +++ /dev/null @@ -1,34 +0,0 @@ -from aiohttp.frozenlist import FrozenList - -__all__ = ("Signal",) - - -class Signal(FrozenList): - """Coroutine-based signal implementation. - - To connect a callback to a signal, use any list method. - - Signals are fired using the send() coroutine, which takes named - arguments. - """ - - __slots__ = ("_owner",) - - def __init__(self, owner): - super().__init__() - self._owner = owner - - def __repr__(self): - return "".format( - self._owner, self.frozen, list(self) - ) - - async def send(self, *args, **kwargs): - """ - Sends data to all registered receivers. - """ - if not self.frozen: - raise RuntimeError("Cannot send non-frozen signal.") - - for receiver in self: - await receiver(*args, **kwargs) # type: ignore diff --git a/aiohttp/signals.pyi b/aiohttp/signals.pyi deleted file mode 100644 index 455f8e2f227..00000000000 --- a/aiohttp/signals.pyi +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Any, Generic, TypeVar - -from aiohttp.frozenlist import FrozenList - -__all__ = ("Signal",) - -_T = TypeVar("_T") - -class Signal(FrozenList[_T], Generic[_T]): - def __init__(self, owner: Any) -> None: ... - def __repr__(self) -> str: ... - async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/aiohttp/test_utils.py b/aiohttp/test_utils.py index 389ace6a8ba..35f4e0a79ec 100644 --- a/aiohttp/test_utils.py +++ b/aiohttp/test_utils.py @@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Type, Union from unittest import mock +from aiosignal import Signal from multidict import CIMultiDict, CIMultiDictProxy from yarl import URL @@ -26,7 +27,6 @@ from .client_ws import ClientWebSocketResponse from .helpers import _SENTINEL, PY_38, sentinel from .http import HttpVersion, RawRequestMessage -from .signals import Signal from .web import ( Application, AppRunner, diff --git a/aiohttp/tracing.py b/aiohttp/tracing.py index 411f8131bbe..435bf3ddf73 100644 --- a/aiohttp/tracing.py +++ b/aiohttp/tracing.py @@ -2,11 +2,11 @@ from types import SimpleNamespace from typing import TYPE_CHECKING, Awaitable, Optional, Type, TypeVar +from aiosignal import Signal from multidict import CIMultiDict from yarl import URL from .client_reqrep import ClientResponse -from .signals import Signal if TYPE_CHECKING: # pragma: no cover from typing_extensions import Protocol diff --git a/aiohttp/web_app.py b/aiohttp/web_app.py index fac6d315134..203e60ac0f6 100644 --- a/aiohttp/web_app.py +++ b/aiohttp/web_app.py @@ -22,12 +22,12 @@ cast, ) +from aiosignal import Signal +from frozenlist import FrozenList from typing_extensions import final from . import hdrs -from .frozenlist import FrozenList from .log import web_logger -from .signals import Signal from .web_middlewares import _fix_request_current_app from .web_request import Request from .web_response import StreamResponse diff --git a/requirements/base.txt b/requirements/base.txt index c108e7da403..639544c15b4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,11 +1,13 @@ -r multidict.txt # required c-ares will not build on windows and has build problems on Macos Python<3.7 aiodns==2.0.0; sys_platform=="linux" or sys_platform=="darwin" and python_version>="3.7" +aiosignal==1.1.2 async-timeout==4.0.0a3 asynctest==0.13.0; python_version<"3.8" Brotli==1.0.9 cchardet==2.1.7 chardet==3.0.4 +frozenlist==1.1.1 gunicorn==20.0.4 typing_extensions==3.7.4.3 uvloop==0.14.0; platform_system!="Windows" and implementation_name=="cpython" and python_version<"3.9" # MagicStack/uvloop#14 diff --git a/setup.py b/setup.py index b9d0f197428..a9edd5d0c8d 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,6 @@ ], define_macros=[("HTTP_PARSER_STRICT", 0)], ), - Extension("aiohttp._frozenlist", ["aiohttp/_frozenlist.c"]), Extension("aiohttp._helpers", ["aiohttp/_helpers.c"]), Extension("aiohttp._http_writer", ["aiohttp/_http_writer.c"]), ] @@ -57,6 +56,8 @@ 'asynctest==0.13.0; python_version<"3.8"', "yarl>=1.0,<2.0", "typing_extensions>=3.7.4", + "frozenlist>=1.1.1", + "aiosignal>=1.1.2", ] diff --git a/tests/test_frozenlist.py b/tests/test_frozenlist.py deleted file mode 100644 index 2211495b47b..00000000000 --- a/tests/test_frozenlist.py +++ /dev/null @@ -1,231 +0,0 @@ -from collections.abc import MutableSequence -from typing import Any - -import pytest - -from aiohttp.frozenlist import FrozenList as CFrozenList, PyFrozenList - - -class FrozenListMixin: - FrozenList: Any = NotImplemented - - SKIP_METHODS: Any = {"__abstractmethods__", "__slots__"} - - def test_subclass(self) -> None: - assert issubclass(self.FrozenList, MutableSequence) - - def test_iface(self) -> None: - for name in set(dir(MutableSequence)) - self.SKIP_METHODS: - if ( - name.startswith("_") and not name.endswith("_") - ) or name == "__class_getitem__": - continue - assert hasattr(self.FrozenList, name) - - def test_ctor_default(self) -> None: - _list = self.FrozenList([]) - assert not _list.frozen - - def test_ctor(self) -> None: - _list = self.FrozenList([1]) - assert not _list.frozen - - def test_ctor_copy_list(self) -> None: - orig = [1] - _list = self.FrozenList(orig) - del _list[0] - assert _list != orig - - def test_freeze(self) -> None: - _list = self.FrozenList() - _list.freeze() - assert _list.frozen - - def test_repr(self) -> None: - _list = self.FrozenList([1]) - assert repr(_list) == "" - _list.freeze() - assert repr(_list) == "" - - def test_getitem(self) -> None: - _list = self.FrozenList([1, 2]) - assert _list[1] == 2 - - def test_setitem(self) -> None: - _list = self.FrozenList([1, 2]) - _list[1] = 3 - assert _list[1] == 3 - - def test_delitem(self) -> None: - _list = self.FrozenList([1, 2]) - del _list[0] - assert len(_list) == 1 - assert _list[0] == 2 - - def test_len(self) -> None: - _list = self.FrozenList([1]) - assert len(_list) == 1 - - def test_iter(self) -> None: - _list = self.FrozenList([1, 2]) - assert list(iter(_list)) == [1, 2] - - def test_reversed(self) -> None: - _list = self.FrozenList([1, 2]) - assert list(reversed(_list)) == [2, 1] - - def test_eq(self) -> None: - _list = self.FrozenList([1]) - assert _list == [1] - - def test_ne(self) -> None: - _list = self.FrozenList([1]) - assert _list != [2] - - def test_le(self) -> None: - _list = self.FrozenList([1]) - assert _list <= [1] - - def test_lt(self) -> None: - _list = self.FrozenList([1]) - assert _list <= [3] - - def test_ge(self) -> None: - _list = self.FrozenList([1]) - assert _list >= [1] - - def test_gt(self) -> None: - _list = self.FrozenList([2]) - assert _list > [1] - - def test_insert(self) -> None: - _list = self.FrozenList([2]) - _list.insert(0, 1) - assert _list == [1, 2] - - def test_frozen_setitem(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list[0] = 2 - - def test_frozen_delitem(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - del _list[0] - - def test_frozen_insert(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.insert(0, 2) - - def test_contains(self) -> None: - _list = self.FrozenList([2]) - assert 2 in _list - - def test_iadd(self) -> None: - _list = self.FrozenList([1]) - _list += [2] - assert _list == [1, 2] - - def test_iadd_frozen(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list += [2] - assert _list == [1] - - def test_index(self) -> None: - _list = self.FrozenList([1]) - assert _list.index(1) == 0 - - def test_remove(self) -> None: - _list = self.FrozenList([1]) - _list.remove(1) - assert len(_list) == 0 - - def test_remove_frozen(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.remove(1) - assert _list == [1] - - def test_clear(self) -> None: - _list = self.FrozenList([1]) - _list.clear() - assert len(_list) == 0 - - def test_clear_frozen(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.clear() - assert _list == [1] - - def test_extend(self) -> None: - _list = self.FrozenList([1]) - _list.extend([2]) - assert _list == [1, 2] - - def test_extend_frozen(self) -> None: - _list = self.FrozenList([1]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.extend([2]) - assert _list == [1] - - def test_reverse(self) -> None: - _list = self.FrozenList([1, 2]) - _list.reverse() - assert _list == [2, 1] - - def test_reverse_frozen(self) -> None: - _list = self.FrozenList([1, 2]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.reverse() - assert _list == [1, 2] - - def test_pop(self) -> None: - _list = self.FrozenList([1, 2]) - assert _list.pop(0) == 1 - assert _list == [2] - - def test_pop_default(self) -> None: - _list = self.FrozenList([1, 2]) - assert _list.pop() == 2 - assert _list == [1] - - def test_pop_frozen(self) -> None: - _list = self.FrozenList([1, 2]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.pop() - assert _list == [1, 2] - - def test_append(self) -> None: - _list = self.FrozenList([1, 2]) - _list.append(3) - assert _list == [1, 2, 3] - - def test_append_frozen(self) -> None: - _list = self.FrozenList([1, 2]) - _list.freeze() - with pytest.raises(RuntimeError): - _list.append(3) - assert _list == [1, 2] - - def test_count(self) -> None: - _list = self.FrozenList([1, 2]) - assert _list.count(1) == 1 - - -class TestFrozenListC(FrozenListMixin): - FrozenList: Any = CFrozenList - - -class TestFrozenListPy(FrozenListMixin): - FrozenList: Any = PyFrozenList diff --git a/tests/test_signals.py b/tests/test_signals.py deleted file mode 100644 index 91ec28f2bbc..00000000000 --- a/tests/test_signals.py +++ /dev/null @@ -1,169 +0,0 @@ -# type: ignore -from typing import Any -from unittest import mock - -import pytest -from multidict import CIMultiDict -from re_assert import Matches - -from aiohttp.signals import Signal -from aiohttp.test_utils import make_mocked_coro, make_mocked_request -from aiohttp.web import Application, Response - - -@pytest.fixture -def app(): - return Application() - - -def make_request(app: Any, method: Any, path: Any, headers: Any = CIMultiDict()): - return make_mocked_request(method, path, headers, app=app) - - -async def test_add_signal_handler_not_a_callable(app: Any) -> None: - callback = True - app.on_response_prepare.append(callback) - app.on_response_prepare.freeze() - with pytest.raises(TypeError): - await app.on_response_prepare(None, None) - - -async def test_function_signal_dispatch(app: Any) -> None: - signal = Signal(app) - kwargs = {"foo": 1, "bar": 2} - - callback_mock = mock.Mock() - - async def callback(**kwargs): - callback_mock(**kwargs) - - signal.append(callback) - signal.freeze() - - await signal.send(**kwargs) - callback_mock.assert_called_once_with(**kwargs) - - -async def test_function_signal_dispatch2(app: Any) -> None: - signal = Signal(app) - args = {"a", "b"} - kwargs = {"foo": 1, "bar": 2} - - callback_mock = mock.Mock() - - async def callback(*args, **kwargs): - callback_mock(*args, **kwargs) - - signal.append(callback) - signal.freeze() - - await signal.send(*args, **kwargs) - callback_mock.assert_called_once_with(*args, **kwargs) - - -async def test_response_prepare(app: Any) -> None: - callback = mock.Mock() - - async def cb(*args, **kwargs): - callback(*args, **kwargs) - - app.on_response_prepare.append(cb) - app.on_response_prepare.freeze() - - request = make_request(app, "GET", "/") - response = Response(body=b"") - await response.prepare(request) - - callback.assert_called_once_with(request, response) - - -async def test_non_coroutine(app: Any) -> None: - signal = Signal(app) - kwargs = {"foo": 1, "bar": 2} - - callback = mock.Mock() - - signal.append(callback) - signal.freeze() - - with pytest.raises(TypeError): - await signal.send(**kwargs) - - -def test_setitem(app: Any) -> None: - signal = Signal(app) - m1 = mock.Mock() - signal.append(m1) - assert signal[0] is m1 - m2 = mock.Mock() - signal[0] = m2 - assert signal[0] is m2 - - -def test_delitem(app: Any) -> None: - signal = Signal(app) - m1 = mock.Mock() - signal.append(m1) - assert len(signal) == 1 - del signal[0] - assert len(signal) == 0 - - -def test_cannot_append_to_frozen_signal(app: Any) -> None: - signal = Signal(app) - m1 = mock.Mock() - m2 = mock.Mock() - signal.append(m1) - signal.freeze() - with pytest.raises(RuntimeError): - signal.append(m2) - - assert list(signal) == [m1] - - -def test_cannot_setitem_in_frozen_signal(app: Any) -> None: - signal = Signal(app) - m1 = mock.Mock() - m2 = mock.Mock() - signal.append(m1) - signal.freeze() - with pytest.raises(RuntimeError): - signal[0] = m2 - - assert list(signal) == [m1] - - -def test_cannot_delitem_in_frozen_signal(app: Any) -> None: - signal = Signal(app) - m1 = mock.Mock() - signal.append(m1) - signal.freeze() - with pytest.raises(RuntimeError): - del signal[0] - - assert list(signal) == [m1] - - -async def test_cannot_send_non_frozen_signal(app: Any) -> None: - signal = Signal(app) - - callback = make_mocked_coro() - - signal.append(callback) - - with pytest.raises(RuntimeError): - await signal.send() - - assert not callback.called - - -async def test_repr(app: Any) -> None: - signal = Signal(app) - - callback = make_mocked_coro() - - signal.append(callback) - - assert Matches( - r", frozen=False, " r"\[\]>" - ) == repr(signal) diff --git a/tests/test_web_response.py b/tests/test_web_response.py index a8ecf95ba2c..a80184029a5 100644 --- a/tests/test_web_response.py +++ b/tests/test_web_response.py @@ -8,11 +8,12 @@ from typing import Any, Optional from unittest import mock +import aiosignal import pytest from multidict import CIMultiDict, CIMultiDictProxy from re_assert import Matches -from aiohttp import HttpVersion, HttpVersion10, HttpVersion11, hdrs, signals +from aiohttp import HttpVersion, HttpVersion10, HttpVersion11, hdrs from aiohttp.payload import BytesPayload from aiohttp.test_utils import make_mocked_coro, make_mocked_request from aiohttp.web import ContentCoding, Response, StreamResponse, json_response @@ -29,7 +30,7 @@ def make_request( app = kwargs.pop("app", None) or mock.Mock() app._debug = False if on_response_prepare is None: - on_response_prepare = signals.Signal(app) + on_response_prepare = aiosignal.Signal(app) app.on_response_prepare = on_response_prepare app.on_response_prepare.freeze() protocol = kwargs.pop("protocol", None) or mock.Mock() @@ -686,7 +687,7 @@ async def test_prepare_twice() -> None: async def test_prepare_calls_signal() -> None: app = mock.Mock() sig = make_mocked_coro() - on_response_prepare = signals.Signal(app) + on_response_prepare = aiosignal.Signal(app) on_response_prepare.append(sig) req = make_request("GET", "/", app=app, on_response_prepare=on_response_prepare) resp = StreamResponse() @@ -1050,7 +1051,7 @@ async def _strip_server(req, res): del res.headers["Server"] app = mock.Mock() - sig = signals.Signal(app) + sig = aiosignal.Signal(app) sig.append(_strip_server) req = make_request("GET", "/", on_response_prepare=sig, app=app) diff --git a/tests/test_web_websocket.py b/tests/test_web_websocket.py index 979e62531a1..65f50991d54 100644 --- a/tests/test_web_websocket.py +++ b/tests/test_web_websocket.py @@ -3,10 +3,11 @@ from typing import Any from unittest import mock +import aiosignal import pytest from multidict import CIMultiDict -from aiohttp import WSMsgType, signals +from aiohttp import WSMsgType from aiohttp.streams import EofStream from aiohttp.test_utils import make_mocked_coro, make_mocked_request from aiohttp.web import HTTPBadRequest, WebSocketResponse @@ -18,7 +19,7 @@ def app(loop: Any): ret = mock.Mock() ret.loop = loop ret._debug = False - ret.on_response_prepare = signals.Signal(ret) + ret.on_response_prepare = aiosignal.Signal(ret) ret.on_response_prepare.freeze() return ret