Date: Tuesday, May 2, 2023 @ 12:03:26 Author: yan12125 Revision: 1455833
archrelease: copy trunk to community-testing-any Added: python-anyio/repos/community-testing-any/PKGBUILD (from rev 1455832, python-anyio/trunk/PKGBUILD) python-anyio/repos/community-testing-any/python-anyio-553.patch (from rev 1455832, python-anyio/trunk/python-anyio-553.patch) Deleted: python-anyio/repos/community-testing-any/PKGBUILD ------------------------+ PKGBUILD | 112 ++++++++++++++------------- python-anyio-553.patch | 189 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 54 deletions(-) Deleted: PKGBUILD =================================================================== --- PKGBUILD 2023-05-02 12:02:44 UTC (rev 1455832) +++ PKGBUILD 2023-05-02 12:03:26 UTC (rev 1455833) @@ -1,54 +0,0 @@ -# Maintainer: Chih-Hsuan Yen <yan12...@archlinux.org> - -pkgname=python-anyio -# https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst -pkgver=3.6.2 -pkgrel=3 -pkgdesc='High level compatibility layer for multiple asynchronous event loop implementations' -arch=(any) -url='https://github.com/agronholm/anyio' -license=(MIT) -depends=(python python-idna python-sniffio) -makedepends=(python-build python-installer python-setuptools python-setuptools-scm python-wheel - python-uvloop python-trio) -checkdepends=(python-pytest python-trustme python-hypothesis python-pytest-mock) -optdepends=( - 'python-trio: trio backend' - 'python-outcome: trio backend' - 'python-uvloop: use uvloop for asyncio backend' - 'python-pytest: pytest plugin' -) -source=(https://github.com/agronholm/anyio/archive/$pkgver/anyio-$pkgver.tar.gz) -sha256sums=('befe8a0e100f6a92ad1b15a6e4adc86bb5f1e055f09b125090300ade5b33534d') - -export SETUPTOOLS_SCM_PRETEND_VERSION=$pkgver - -prepare() { - cd anyio-$pkgver - # Remove "error" from pytest filterwarnings - sed -i '/"error"/d' pyproject.toml - # XXX: Temporarily remove testing trio as a backend. anyio 3.x is known to be incompatible with trio >= 0.22 - # https://github.com/agronholm/anyio/commit/787cb0c2e53c2a3307873d202fbd49dc5eac4e96 - sed -i '/"trio"/d' tests/conftest.py -} - -build() { - cd anyio-$pkgver - python -m build --wheel --no-isolation -} - -check() { - cd anyio-$pkgver - # Install to a temporary root as the test suite requires the entry point for - # its pytest plugin - pyver=$(python -c "import sys; print('{}.{}'.format(*sys.version_info[:2]))") - python -m installer --destdir="$PWD/tmp_install" dist/*.whl - # Several TLS tests failed with Python 3.11.3 https://github.com/agronholm/anyio/issues/550 - PYTHONPATH="$PWD/tmp_install/usr/lib/python$pyver/site-packages" pytest -k 'not TestTLSStream and not TestTLSListener' -} - -package() { - cd anyio-$pkgver - python -m installer --destdir="$pkgdir" dist/*.whl - install -Dm644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname -} Copied: python-anyio/repos/community-testing-any/PKGBUILD (from rev 1455832, python-anyio/trunk/PKGBUILD) =================================================================== --- PKGBUILD (rev 0) +++ PKGBUILD 2023-05-02 12:03:26 UTC (rev 1455833) @@ -0,0 +1,58 @@ +# Maintainer: Chih-Hsuan Yen <yan12...@archlinux.org> + +pkgname=python-anyio +# https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst +pkgver=3.6.2 +pkgrel=4 +pkgdesc='High level compatibility layer for multiple asynchronous event loop implementations' +arch=(any) +url='https://github.com/agronholm/anyio' +license=(MIT) +depends=(python python-idna python-sniffio) +makedepends=(python-build python-installer python-setuptools python-setuptools-scm python-wheel + python-uvloop python-trio) +checkdepends=(python-pytest python-trustme python-hypothesis python-pytest-mock) +optdepends=( + 'python-trio: trio backend' + 'python-outcome: trio backend' + 'python-uvloop: use uvloop for asyncio backend' + 'python-pytest: pytest plugin' +) +source=(https://github.com/agronholm/anyio/archive/$pkgver/anyio-$pkgver.tar.gz + $pkgname-553.patch) +sha256sums=('befe8a0e100f6a92ad1b15a6e4adc86bb5f1e055f09b125090300ade5b33534d' + '4d500b72e1c8669c8944ea4deb2bacecfb679f49efee054c49fc0ee7aea8f9df') + +export SETUPTOOLS_SCM_PRETEND_VERSION=$pkgver + +prepare() { + cd anyio-$pkgver + # Remove "error" from pytest filterwarnings + sed -i '/"error"/d' pyproject.toml + # XXX: Temporarily remove testing trio as a backend. anyio 3.x is known to be incompatible with trio >= 0.22 + # https://github.com/agronholm/anyio/commit/787cb0c2e53c2a3307873d202fbd49dc5eac4e96 + sed -i '/"trio"/d' tests/conftest.py + # Backported from https://github.com/agronholm/anyio/pull/553 (merged to git master) + patch -Np1 -i ../$pkgname-553.patch +} + +build() { + cd anyio-$pkgver + python -m build --wheel --no-isolation +} + +check() { + cd anyio-$pkgver + # Install to a temporary root as the test suite requires the entry point for + # its pytest plugin + pyver=$(python -c "import sys; print('{}.{}'.format(*sys.version_info[:2]))") + python -m installer --destdir="$PWD/tmp_install" dist/*.whl + # Several TLS tests failed with Python 3.11.3 https://github.com/agronholm/anyio/issues/550 + PYTHONPATH="$PWD/tmp_install/usr/lib/python$pyver/site-packages" pytest +} + +package() { + cd anyio-$pkgver + python -m installer --destdir="$pkgdir" dist/*.whl + install -Dm644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname +} Copied: python-anyio/repos/community-testing-any/python-anyio-553.patch (from rev 1455832, python-anyio/trunk/python-anyio-553.patch) =================================================================== --- python-anyio-553.patch (rev 0) +++ python-anyio-553.patch 2023-05-02 12:03:26 UTC (rev 1455833) @@ -0,0 +1,189 @@ +diff --git a/src/anyio/streams/tls.py b/src/anyio/streams/tls.py +index c8e19e2..05a70cb 100644 +--- a/src/anyio/streams/tls.py ++++ b/src/anyio/streams/tls.py +@@ -37,8 +37,9 @@ class TLSAttribute(TypedAttributeSet): + peer_certificate_binary: Optional[bytes] = typed_attribute() + #: ``True`` if this is the server side of the connection + server_side: bool = typed_attribute() +- #: ciphers shared between both ends of the TLS connection +- shared_ciphers: List[Tuple[str, str, int]] = typed_attribute() ++ #: ciphers shared by the client during the TLS handshake (``None`` if this is the ++ #: client side) ++ shared_ciphers: Optional[List[Tuple[str, str, int]]] = typed_attribute() + #: the :class:`~ssl.SSLObject` used for encryption + ssl_object: ssl.SSLObject = typed_attribute() + #: ``True`` if this stream does (and expects) a closing TLS handshake when the stream is being +@@ -105,7 +106,7 @@ class TLSStream(ByteStream): + + # Re-enable detection of unexpected EOFs if it was disabled by Python + if hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"): +- ssl_context.options ^= ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] ++ ssl_context.options &= ~ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] + + bio_in = ssl.MemoryBIO() + bio_out = ssl.MemoryBIO() +@@ -228,7 +229,9 @@ class TLSStream(ByteStream): + True + ), + TLSAttribute.server_side: lambda: self._ssl_object.server_side, +- TLSAttribute.shared_ciphers: lambda: self._ssl_object.shared_ciphers(), ++ TLSAttribute.shared_ciphers: lambda: self._ssl_object.shared_ciphers() ++ if self._ssl_object.server_side ++ else None, + TLSAttribute.standard_compatible: lambda: self.standard_compatible, + TLSAttribute.ssl_object: lambda: self._ssl_object, + TLSAttribute.tls_version: self._ssl_object.version, +diff --git a/tests/conftest.py b/tests/conftest.py +index 6ee5a53..5d032be 100644 +--- a/tests/conftest.py ++++ b/tests/conftest.py +@@ -54,7 +54,7 @@ def ca() -> CA: + def server_context(ca: CA) -> SSLContext: + server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + if hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"): +- server_context.options ^= ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] ++ server_context.options &= ~ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] + + ca.issue_cert("localhost").configure_cert(server_context) + return server_context +@@ -64,7 +64,7 @@ def server_context(ca: CA) -> SSLContext: + def client_context(ca: CA) -> SSLContext: + client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) + if hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"): +- client_context.options ^= ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] ++ client_context.options &= ~ssl.OP_IGNORE_UNEXPECTED_EOF # type: ignore[attr-defined] + + ca.configure_trust(client_context) + return client_context +diff --git a/tests/streams/test_tls.py b/tests/streams/test_tls.py +index 73ccfad..4d3a263 100644 +--- a/tests/streams/test_tls.py ++++ b/tests/streams/test_tls.py +@@ -5,6 +5,7 @@ from threading import Thread + from typing import ContextManager, NoReturn + + import pytest ++from pytest_mock import MockerFixture + from trustme import CA + + from anyio import ( +@@ -12,10 +13,13 @@ from anyio import ( + EndOfStream, + Event, + connect_tcp, ++ create_memory_object_stream, + create_task_group, + create_tcp_listener, ++ to_thread, + ) + from anyio.abc import AnyByteStream, SocketAttribute, SocketStream ++from anyio.streams.stapled import StapledObjectStream + from anyio.streams.tls import TLSAttribute, TLSListener, TLSStream + + pytestmark = pytest.mark.anyio +@@ -95,7 +99,7 @@ class TestTLSStream: + wrapper.extra(TLSAttribute.peer_certificate_binary), bytes + ) + assert wrapper.extra(TLSAttribute.server_side) is False +- assert isinstance(wrapper.extra(TLSAttribute.shared_ciphers), list) ++ assert wrapper.extra(TLSAttribute.shared_ciphers) is None + assert isinstance(wrapper.extra(TLSAttribute.ssl_object), ssl.SSLObject) + assert wrapper.extra(TLSAttribute.standard_compatible) is False + assert wrapper.extra(TLSAttribute.tls_version).startswith("TLSv") +@@ -368,6 +372,20 @@ class TestTLSStream: + server_thread.join() + server_sock.close() + ++ @pytest.mark.skipif( ++ not hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"), ++ reason="The ssl module does not have the OP_IGNORE_UNEXPECTED_EOF attribute", ++ ) ++ async def test_default_context_ignore_unexpected_eof_flag_off( ++ self, mocker: MockerFixture ++ ) -> None: ++ send1, receive1 = create_memory_object_stream() ++ client_stream = StapledObjectStream(send1, receive1) ++ mocker.patch.object(TLSStream, "_call_sslobject_method") ++ tls_stream = await TLSStream.wrap(client_stream) ++ ssl_context = tls_stream.extra(TLSAttribute.ssl_object).context ++ assert not ssl_context.options & ssl.OP_IGNORE_UNEXPECTED_EOF ++ + + class TestTLSListener: + async def test_handshake_fail(self, server_context: ssl.SSLContext) -> None: +@@ -399,3 +417,74 @@ class TestTLSListener: + tg.cancel_scope.cancel() + + assert isinstance(exception, BrokenResourceError) ++ ++ async def test_extra_attributes( ++ self, client_context: ssl.SSLContext, server_context: ssl.SSLContext, ca: CA ++ ) -> None: ++ def connect_sync(addr: tuple[str, int]) -> None: ++ with socket.create_connection(addr) as plain_sock: ++ plain_sock.settimeout(2) ++ with client_context.wrap_socket( ++ plain_sock, ++ server_side=False, ++ server_hostname="localhost", ++ suppress_ragged_eofs=False, ++ ) as conn: ++ conn.recv(1) ++ conn.unwrap() ++ ++ class CustomTLSListener(TLSListener): ++ @staticmethod ++ async def handle_handshake_error( ++ exc: BaseException, stream: AnyByteStream ++ ) -> None: ++ await TLSListener.handle_handshake_error(exc, stream) ++ pytest.fail("TLS handshake failed") ++ ++ async def handler(stream: TLSStream) -> None: ++ async with stream: ++ try: ++ assert stream.extra(TLSAttribute.alpn_protocol) == "h2" ++ assert isinstance( ++ stream.extra(TLSAttribute.channel_binding_tls_unique), bytes ++ ) ++ assert isinstance(stream.extra(TLSAttribute.cipher), tuple) ++ assert isinstance(stream.extra(TLSAttribute.peer_certificate), dict) ++ assert isinstance( ++ stream.extra(TLSAttribute.peer_certificate_binary), bytes ++ ) ++ assert stream.extra(TLSAttribute.server_side) is True ++ shared_ciphers = stream.extra(TLSAttribute.shared_ciphers) ++ assert isinstance(shared_ciphers, list) ++ assert len(shared_ciphers) > 1 ++ assert isinstance( ++ stream.extra(TLSAttribute.ssl_object), ssl.SSLObject ++ ) ++ assert stream.extra(TLSAttribute.standard_compatible) is True ++ assert stream.extra(TLSAttribute.tls_version).startswith("TLSv") ++ finally: ++ event.set() ++ await stream.send(b"\x00") ++ ++ # Issue a client certificate and make the server trust it ++ client_cert = ca.issue_cert("dummy-client") ++ client_cert.configure_cert(client_context) ++ ca.configure_trust(server_context) ++ server_context.verify_mode = ssl.CERT_REQUIRED ++ ++ event = Event() ++ server_context.set_alpn_protocols(["h2"]) ++ client_context.set_alpn_protocols(["h2"]) ++ listener = await create_tcp_listener(local_host="127.0.0.1") ++ tls_listener = CustomTLSListener(listener, server_context) ++ async with tls_listener, create_task_group() as tg: ++ assert tls_listener.extra(TLSAttribute.standard_compatible) is True ++ tg.start_soon(tls_listener.serve, handler) ++ client_thread = Thread( ++ target=connect_sync, ++ args=[listener.extra(SocketAttribute.local_address)], ++ ) ++ client_thread.start() ++ await event.wait() ++ await to_thread.run_sync(client_thread.join) ++ tg.cancel_scope.cancel()