diff --git a/CHANGES/7280.bugfix b/CHANGES/7280.bugfix new file mode 100644 index 00000000000..6fc6ef28f80 --- /dev/null +++ b/CHANGES/7280.bugfix @@ -0,0 +1 @@ +Fixed an exception and possible memory leak in Python 3.11.1+ -- by :user:`Dreamsorcerer` diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 959a81c47a4..02875a968a0 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -354,7 +354,7 @@ def _cleanup_closed(self) -> None: self._cleanup_closed_handle.cancel() for transport in self._cleanup_closed_transports: - if transport is not None: + if transport is not None and not transport.is_closing(): transport.abort() self._cleanup_closed_transports = [] @@ -409,7 +409,7 @@ def _close_immediately(self) -> List["asyncio.Future[None]"]: # TODO (A.Yushovskiy, 24-May-2019) collect transp. closing futures for transport in self._cleanup_closed_transports: - if transport is not None: + if transport is not None and not transport.is_closing(): transport.abort() return waiters diff --git a/tests/test_connector.py b/tests/test_connector.py index e6ff68592cb..013dd6dc5d2 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -1179,7 +1179,8 @@ async def test_cleanup_closed(loop: Any, mocker: Any) -> None: mocker.spy(loop, "call_at") conn = aiohttp.BaseConnector(enable_cleanup_closed=True) - tr = mock.Mock() + tr = mock.create_autospec(asyncio.Transport, spec_set=True, instance=True) + tr.is_closing.return_value = False conn._cleanup_closed_handle = cleanup_closed_handle = mock.Mock() conn._cleanup_closed_transports = [tr] conn._cleanup_closed() @@ -1189,10 +1190,11 @@ async def test_cleanup_closed(loop: Any, mocker: Any) -> None: assert cleanup_closed_handle.cancel.called -async def test_cleanup_closed_disabled(loop: Any, mocker: Any) -> None: +async def test_cleanup_closed_disabled(loop: Any) -> None: conn = aiohttp.BaseConnector(enable_cleanup_closed=False) - tr = mock.Mock() + tr = mock.create_autospec(asyncio.Transport, spec_set=True, instance=True) + tr.is_closing.return_value = False conn._cleanup_closed_transports = [tr] conn._cleanup_closed() assert tr.abort.called @@ -1343,14 +1345,15 @@ async def test_close_cancels_cleanup_handle(loop: Any) -> None: async def test_close_abort_closed_transports(loop: Any) -> None: - tr = mock.Mock() + tr = mock.create_autospec(asyncio.Transport, spec_set=True, instance=True) + tr.is_closing.return_value = True conn = aiohttp.BaseConnector() conn._cleanup_closed_transports.append(tr) await conn.close() assert not conn._cleanup_closed_transports - assert tr.abort.called + assert not tr.abort.called assert conn.closed