[Python-modules-team] Bug#964750: hypercorn build-dependencies unsatisfiable in testing.

peter green plugwash at p10link.net
Thu Jul 9 22:39:00 BST 2020


Package: hypercorn
Version: 0.9.4-1
Severity: serious
Tags: patch
Justification: rc policy "packages must be buildable within the same release"

hypercorn build-depends on python3-asynctest, which is built from the python-asynctest source
package.

According to bug 954554 python3-asynctest is incompatible with the version of python3 currently
in testing/unstable. A patch exists but according to discussion in that bug report it has been
rejected by both the upstream and the Debian maintainers of python-asynctest.

As a result the python-asynctest and hypercorn source packages (and their corresponding binary
packages) were autoremoved from testing on the 1st of June.

Unfortunately, due to a bug in the testing migration scripts* hypercorn re-entered testing on the
26th of June.

Bug 954554 had a link to an upstream patch for hypercorn to stop using, I applied the relavent parts
of said upstream patch to the Debian hypercorn package, updated the build-dependencies accordingly
and was able to succesfully build the package.

Alternatively the upstream change seems to be included in the latest upstream release of hypercorn,
so uploading that would be another option.

A debdiff is attached, I may upload this later as a team upload (I don't see how this patch can
affect runtime functionality but I'd still rather get a sanity check from someone who actually.
uses the package).

* see https://lists.debian.org/debian-release/2020/06/msg00375.html
-------------- next part --------------
diff -Nru hypercorn-0.9.4/debian/changelog hypercorn-0.9.4/debian/changelog
--- hypercorn-0.9.4/debian/changelog	2020-04-17 11:36:29.000000000 +0000
+++ hypercorn-0.9.4/debian/changelog	2020-07-09 19:51:28.000000000 +0000
@@ -1,3 +1,13 @@
+hypercorn (0.9.4-2) UNRELEASED; urgency=medium
+
+  * Team upload.
+  * Apply upstream patch to move away from asynctest and move towards
+    the testing functionality in the standard library.
+  * Update build-depenencies, remove build-dependency on python3-asynctest
+    and add build-dependency on python3-all-dev (>= 3.8.2-3) | python3-mock
+
+ -- Peter Michael Green <plugwash at debian.org>  Thu, 09 Jul 2020 19:51:28 +0000
+
 hypercorn (0.9.4-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru hypercorn-0.9.4/debian/control hypercorn-0.9.4/debian/control
--- hypercorn-0.9.4/debian/control	2020-04-17 11:36:29.000000000 +0000
+++ hypercorn-0.9.4/debian/control	2020-07-09 19:51:28.000000000 +0000
@@ -14,7 +14,7 @@
  python3-priority,
  python3-toml,
  python3-typing-extensions,
- python3-asynctest,
+ python3-all-dev (>= 3.8.2-3) | python3-mock,
  python3-hypothesis,
  python3-pytest,
  python3-pytest-asyncio,
diff -Nru hypercorn-0.9.4/debian/patches/series hypercorn-0.9.4/debian/patches/series
--- hypercorn-0.9.4/debian/patches/series	1970-01-01 00:00:00.000000000 +0000
+++ hypercorn-0.9.4/debian/patches/series	2020-07-09 19:46:12.000000000 +0000
@@ -0,0 +1 @@
+update-testing.patch
diff -Nru hypercorn-0.9.4/debian/patches/update-testing.patch hypercorn-0.9.4/debian/patches/update-testing.patch
--- hypercorn-0.9.4/debian/patches/update-testing.patch	1970-01-01 00:00:00.000000000 +0000
+++ hypercorn-0.9.4/debian/patches/update-testing.patch	2020-07-09 19:51:18.000000000 +0000
@@ -0,0 +1,274 @@
+This patch is based on the upstream commit detailed below and was
+adapted to apply to the Debian hypercorn package by Peter Michael
+Green
+
+Specifically  changes to tox.ini and .gitlab-ci.yml were removed
+from the patch as those files do not  seem to exist in the Debian
+Hypercorn 0.9.4 Package.
+
+
+commit 80e2ad5db107c42d42471ea64764d2b42202349c
+Author: pgjones <philip.graham.jones at googlemail.com>
+Date:   Sun May 31 18:53:02 2020 +0100
+
+    Update testing
+    
+    Switch from asynctest to the stdlib (with a backport as AsyncMock was
+    introduced in 3.8) and update the base python versions to 3.8.
+
+diff --git a/setup.cfg b/setup.cfg
+index 3e4a8f0..36c4ad2 100644
+--- a/setup.cfg
++++ b/setup.cfg
+@@ -21,9 +21,6 @@ ignore_missing_imports = True
+ [mypy-aioquic.*]
+ ignore_missing_imports = True
+ 
+-[mypy-asynctest.*]
+-ignore_missing_imports = True
+-
+ [mypy-cryptography.*]
+ ignore_missing_imports = True
+ 
+diff --git a/setup.py b/setup.py
+index 5e4e461..392ef5a 100644
+--- a/setup.py
++++ b/setup.py
+@@ -25,8 +25,8 @@ INSTALL_REQUIRES = [
+ ]
+ 
+ TESTS_REQUIRE = [
+-    "asynctest",
+     "hypothesis",
++    "mock",
+     "pytest",
+     "pytest-asyncio",
+     "pytest-cov",
+diff --git a/tests/protocol/test_h11.py b/tests/protocol/test_h11.py
+index 3a635fa..eaef1dd 100755
+--- a/tests/protocol/test_h11.py
++++ b/tests/protocol/test_h11.py
+@@ -1,13 +1,12 @@
+ import asyncio
+ from typing import Any
+-from unittest.mock import call
++from unittest.mock import call, Mock
+ 
+ import h11
+ import pytest
+ from _pytest.monkeypatch import MonkeyPatch
+ 
+ import hypercorn.protocol.h11
+-from asynctest.mock import CoroutineMock, Mock as AsyncMock
+ from hypercorn.asyncio.tcp_server import EventWrapper
+ from hypercorn.config import Config
+ from hypercorn.events import Closed, RawData, Updated
+@@ -16,17 +15,24 @@ from hypercorn.protocol.h11 import H2CProtocolRequired, H2ProtocolAssumed, H11Pr
+ from hypercorn.protocol.http_stream import HTTPStream
+ from hypercorn.typing import Event as IOEvent
+ 
++try:
++    from unittest.mock import AsyncMock
++except ImportError:
++    # Python < 3.8
++    from mock import AsyncMock
++
++
+ BASIC_HEADERS = [("Host", "hypercorn"), ("Connection", "close")]
+ 
+ 
+ @pytest.fixture(name="protocol")
+ async def _protocol(monkeypatch: MonkeyPatch) -> H11Protocol:
+-    MockHTTPStream = AsyncMock()  # noqa: N806
++    MockHTTPStream = Mock()  # noqa: N806
+     MockHTTPStream.return_value = AsyncMock(spec=HTTPStream)
+     monkeypatch.setattr(hypercorn.protocol.h11, "HTTPStream", MockHTTPStream)
+-    MockEvent = AsyncMock()  # noqa: N806
++    MockEvent = Mock()  # noqa: N806
+     MockEvent.return_value = AsyncMock(spec=IOEvent)
+-    return H11Protocol(Config(), False, None, None, CoroutineMock(), CoroutineMock(), MockEvent)
++    return H11Protocol(Config(), False, None, None, AsyncMock(), AsyncMock(), MockEvent)
+ 
+ 
+ @pytest.mark.asyncio
+@@ -228,9 +234,9 @@ async def test_protocol_handle_max_incomplete(monkeypatch: MonkeyPatch) -> None:
+     MockHTTPStream = AsyncMock()  # noqa: N806
+     MockHTTPStream.return_value = AsyncMock(spec=HTTPStream)
+     monkeypatch.setattr(hypercorn.protocol.h11, "HTTPStream", MockHTTPStream)
+-    MockEvent = AsyncMock()  # noqa: N806
++    MockEvent = Mock()  # noqa: N806
+     MockEvent.return_value = AsyncMock(spec=IOEvent)
+-    protocol = H11Protocol(config, False, None, None, CoroutineMock(), CoroutineMock(), MockEvent)
++    protocol = H11Protocol(config, False, None, None, AsyncMock(), AsyncMock(), MockEvent)
+     await protocol.handle(RawData(data=b"GET / HTTP/1.1\r\nHost: hypercorn\r\n"))
+     protocol.send.assert_called()
+     assert protocol.send.call_args_list == [
+diff --git a/tests/protocol/test_h2.py b/tests/protocol/test_h2.py
+index 8d4e2ad..2d63d9a 100644
+--- a/tests/protocol/test_h2.py
++++ b/tests/protocol/test_h2.py
+@@ -1,17 +1,22 @@
+ import asyncio
+-from unittest.mock import call
++from unittest.mock import call, Mock
+ 
+ import pytest
+ from _pytest.monkeypatch import MonkeyPatch
+ 
+ import hypercorn.protocol.h2
+-from asynctest.mock import CoroutineMock, Mock as AsyncMock
+ from hypercorn.asyncio.tcp_server import EventWrapper
+ from hypercorn.config import Config
+ from hypercorn.events import Closed, RawData
+ from hypercorn.protocol.h2 import BUFFER_HIGH_WATER, H2Protocol, StreamBuffer
+ from hypercorn.protocol.http_stream import HTTPStream
+ 
++try:
++    from unittest.mock import AsyncMock
++except ImportError:
++    # Python < 3.8
++    from mock import AsyncMock
++
+ 
+ @pytest.mark.asyncio
+ async def test_stream_buffer_push_and_pop(event_loop: asyncio.AbstractEventLoop) -> None:
+@@ -68,10 +73,10 @@ async def test_stream_buffer_complete(event_loop: asyncio.AbstractEventLoop) ->
+ 
+ @pytest.fixture(name="protocol")
+ async def _protocol(monkeypatch: MonkeyPatch) -> H2Protocol:
+-    MockHTTPStream = AsyncMock()  # noqa: N806
++    MockHTTPStream = Mock()  # noqa: N806
+     MockHTTPStream.return_value = AsyncMock(spec=HTTPStream)
+     monkeypatch.setattr(hypercorn.protocol.h11, "HTTPStream", MockHTTPStream)
+-    return H2Protocol(Config(), False, None, None, CoroutineMock(), CoroutineMock(), EventWrapper)
++    return H2Protocol(Config(), False, None, None, AsyncMock(), AsyncMock(), EventWrapper)
+ 
+ 
+ @pytest.mark.asyncio
+diff --git a/tests/protocol/test_http_stream.py b/tests/protocol/test_http_stream.py
+index 2df1762..6510a37 100644
+--- a/tests/protocol/test_http_stream.py
++++ b/tests/protocol/test_http_stream.py
+@@ -3,18 +3,23 @@ from unittest.mock import call
+ 
+ import pytest
+ 
+-from asynctest.mock import CoroutineMock, Mock as AsyncMock
+ from hypercorn.config import Config
+ from hypercorn.logging import Logger
+ from hypercorn.protocol.events import Body, EndBody, Request, Response, StreamClosed
+ from hypercorn.protocol.http_stream import ASGIHTTPState, HTTPStream
+ from hypercorn.utils import UnexpectedMessage
+ 
++try:
++    from unittest.mock import AsyncMock
++except ImportError:
++    # Python < 3.8
++    from mock import AsyncMock
++
+ 
+ @pytest.fixture(name="stream")
+ async def _stream() -> HTTPStream:
+-    stream = HTTPStream(Config(), False, None, None, CoroutineMock(), CoroutineMock(), 1)
+-    stream.app_put = CoroutineMock()
++    stream = HTTPStream(Config(), False, None, None, AsyncMock(), AsyncMock(), 1)
++    stream.app_put = AsyncMock()
+     stream.config._log = AsyncMock(spec=Logger)
+     return stream
+ 
+@@ -78,7 +83,7 @@ async def test_handle_body(stream: HTTPStream) -> None:
+ 
+ @pytest.mark.asyncio
+ async def test_handle_end_body(stream: HTTPStream) -> None:
+-    stream.app_put = CoroutineMock()
++    stream.app_put = AsyncMock()
+     await stream.handle(EndBody(stream_id=1))
+     stream.app_put.assert_called()
+     assert stream.app_put.call_args_list == [
+diff --git a/tests/protocol/test_ws_stream.py b/tests/protocol/test_ws_stream.py
+index 7d70c4f..91c2a66 100644
+--- a/tests/protocol/test_ws_stream.py
++++ b/tests/protocol/test_ws_stream.py
+@@ -4,7 +4,6 @@ from unittest.mock import call, Mock
+ import pytest
+ from wsproto.events import BytesMessage, TextMessage
+ 
+-from asynctest.mock import CoroutineMock, Mock as AsyncMock
+ from hypercorn.config import Config
+ from hypercorn.logging import Logger
+ from hypercorn.protocol.events import Body, Data, EndBody, EndData, Request, Response, StreamClosed
+@@ -17,6 +16,12 @@ from hypercorn.protocol.ws_stream import (
+ )
+ from hypercorn.utils import UnexpectedMessage
+ 
++try:
++    from unittest.mock import AsyncMock
++except ImportError:
++    # Python < 3.8
++    from mock import AsyncMock
++
+ 
+ def test_buffer() -> None:
+     buffer_ = WebsocketBuffer(10)
+@@ -126,9 +131,9 @@ def test_handshake_accept_http2() -> None:
+ 
+ @pytest.fixture(name="stream")
+ async def _stream() -> WSStream:
+-    stream = WSStream(Config(), False, None, None, CoroutineMock(), CoroutineMock(), 1)
+-    stream.spawn_app.return_value = CoroutineMock()
+-    stream.app_put = CoroutineMock()
++    stream = WSStream(Config(), False, None, None, AsyncMock(), AsyncMock(), 1)
++    stream.spawn_app.return_value = AsyncMock()
++    stream.app_put = AsyncMock()
+     stream.config._log = AsyncMock(spec=Logger)
+     return stream
+ 
+@@ -175,7 +180,7 @@ async def test_handle_connection(stream: WSStream) -> None:
+         )
+     )
+     await stream.app_send({"type": "websocket.accept"})
+-    stream.app_put = CoroutineMock()
++    stream.app_put = AsyncMock()
+     await stream.handle(Data(stream_id=1, data=b"\x81\x85&`\x13\x0eN\x05\x7fbI"))
+     stream.app_put.assert_called()
+     assert stream.app_put.call_args_list == [
+diff --git a/tests/trio/test_sanity.py b/tests/trio/test_sanity.py
+index 4d4e47d..0c12e4c 100644
+--- a/tests/trio/test_sanity.py
++++ b/tests/trio/test_sanity.py
+@@ -6,11 +6,16 @@ import pytest
+ import trio
+ import wsproto
+ 
+-from asynctest.mock import CoroutineMock
+ from hypercorn.config import Config
+ from hypercorn.trio.tcp_server import TCPServer
+ from ..helpers import MockSocket, SANITY_BODY, sanity_framework
+ 
++try:
++    from unittest.mock import AsyncMock
++except ImportError:
++    # Python < 3.8
++    from mock import AsyncMock
++
+ 
+ @pytest.mark.trio
+ async def test_http1_request(nursery: trio._core._run.Nursery) -> None:
+@@ -92,7 +97,7 @@ async def test_http1_websocket(nursery: trio._core._run.Nursery) -> None:
+ async def test_http2_request(nursery: trio._core._run.Nursery) -> None:
+     client_stream, server_stream = trio.testing.memory_stream_pair()
+     server_stream.transport_stream = Mock(return_value=PropertyMock(return_value=MockSocket()))
+-    server_stream.do_handshake = CoroutineMock()
++    server_stream.do_handshake = AsyncMock()
+     server_stream.selected_alpn_protocol = Mock(return_value="h2")
+     server = TCPServer(sanity_framework, Config(), server_stream)
+     nursery.start_soon(server.run)
+@@ -147,7 +152,7 @@ async def test_http2_request(nursery: trio._core._run.Nursery) -> None:
+ async def test_http2_websocket(nursery: trio._core._run.Nursery) -> None:
+     client_stream, server_stream = trio.testing.memory_stream_pair()
+     server_stream.transport_stream = Mock(return_value=PropertyMock(return_value=MockSocket()))
+-    server_stream.do_handshake = CoroutineMock()
++    server_stream.do_handshake = AsyncMock()
+     server_stream.selected_alpn_protocol = Mock(return_value="h2")
+     server = TCPServer(sanity_framework, Config(), server_stream)
+     nursery.start_soon(server.run)


More information about the Python-modules-team mailing list