diff --git a/testing/py3-falcon/APKBUILD b/testing/py3-falcon/APKBUILD new file mode 100644 index 0000000000000000000000000000000000000000..507e4ce160b5f09acec4189bb1b52d0c83599994 --- /dev/null +++ b/testing/py3-falcon/APKBUILD @@ -0,0 +1,65 @@ +# Maintainer: Noel Kuntze <noel.kuntze@contauro.com> +pkgname=py3-falcon +pkgdesc="Web API framework for fast and reliable microservices, proxies, and app backends" +pkgver=3.1.3 +pkgrel=0 +arch="all" +url="https://falconframework.org/" +license="Apache-2.0" +makedepends=" + py3-gpep517 + py3-setuptools + py3-wheel + python3-dev + cython + " +checkdepends=" + py3-coverage + py3-pytest + py3-pyaml + py3-requests + py3-pytest-asyncio + py3-aiofiles + py3-httpx + uvicorn + py3-websockets + py3-cbor2 + py3-msgpack + py3-mujson + py3-ujson + py3-rapidjson + py3-orjson + py3-gunicorn + py3-daphne + py3-waitress + " + +subpackages="$pkgname-pyc" + +source="$pkgname-$pkgver.tar.gz::https://github.com/falconry/falcon/archive/refs/tags/$pkgver.tar.gz + python-3.12.patch + " + +builddir="$srcdir"/falcon-$pkgver + +build() { + gpep517 build-wheel \ + --wheel-dir dist \ + --output-fd 3 3>&1 >&2 +} + +check() { + local _site_packages=$(python -c "import site; print(site.getsitepackages()[0])") + python3 -m installer -d test_dir dist/*.whl + export PYTHONPATH="$PWD/test_dir/$_site_packages:$PYTHONPATH" + pytest -vv tests/ +} + +package() { + python3 -m installer -d "$pkgdir" dist/*.whl +} + +sha512sums=" +66c5f563b373eb2bc2576d64d2225fa98f4d9d80dc1c93f6831f17287738797ac1f08a1ba71f4a70e6bafad7a51f70fa6fbbee99ef521419ceedcf2d892108ee py3-falcon-3.1.3.tar.gz +c9b7eb3058df517e7880584292b9a46415f437c9cddff8ddab8d1bcb7cf0e2cc5ef8ebd6e4c5ad2dd243aefc02e4664a91a885cc15b7c97e75ba430bfa669e95 python-3.12.patch +" diff --git a/testing/py3-falcon/python-3.12.patch b/testing/py3-falcon/python-3.12.patch new file mode 100644 index 0000000000000000000000000000000000000000..6bc9b6a2dedcf25c33d9ea26963df897aa8b6112 --- /dev/null +++ b/testing/py3-falcon/python-3.12.patch @@ -0,0 +1,116 @@ +From a78cfb38a0c0f6031cc3ff39ff8bf4afd03ef008 Mon Sep 17 00:00:00 2001 +From: Vytautas Liuolia <vytautas.liuolia@gmail.com> +Date: Thu, 21 Mar 2024 20:59:26 +0100 +Subject: [PATCH] chore(sync): use `asyncio.Runner` for `async_to_sync()` on + py311+ (#2216) + +* chore(asyncio): replace `get_event_loop()` -> `get_running_loop()` where applicable + +* chore(sync): use `asyncio.Runner` for `async_to_sync()` on py311+ + +* chore(sync): exempt a line from coverage as it can only be hit on 3.11+ + +* chore(tests/asgi): adapt to Uvicorn now propagating signals to retcode + +* chore(tests/asgi): do not check ASGI server retcode on Windows + +* chore(tests/asgi): check for a M$ Windows specific exit code constant + +* chore(sync): use a nicer pattern to get the active runner +--- + falcon/util/sync.py | 60 ++++++++++++++++++++++++--------- + pyproject.toml | 1 - + tests/asgi/test_asgi_servers.py | 10 ++++-- + tests/asgi/test_scope.py | 6 ++-- + tests/dump_asgi.py | 2 +- + 5 files changed, 56 insertions(+), 23 deletions(-) + +diff --git a/pyproject.toml b/pyproject.toml +index ad445ce55..5ed0c5fab 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -97,7 +97,6 @@ filterwarnings = [ + "ignore:.cgi. is deprecated and slated for removal:DeprecationWarning", + "ignore:path is deprecated\\. Use files\\(\\) instead:DeprecationWarning", + "ignore:This process \\(.+\\) is multi-threaded", +- "ignore:There is no current event loop", + ] + testpaths = [ + "tests" +diff --git a/tests/asgi/test_asgi_servers.py b/tests/asgi/test_asgi_servers.py +index 26f51ad0c..321e41f96 100644 +--- a/tests/asgi/test_asgi_servers.py ++++ b/tests/asgi/test_asgi_servers.py +@@ -4,6 +4,7 @@ + import os + import platform + import random ++import signal + import subprocess + import sys + import time +@@ -27,7 +28,9 @@ + _SERVER_HOST = '127.0.0.1' + _SIZE_1_KB = 1024 + _SIZE_1_MB = _SIZE_1_KB**2 +- ++# NOTE(vytas): Windows specific: {Application Exit by CTRL+C}. ++# The application terminated as a result of a CTRL+C. ++_STATUS_CONTROL_C_EXIT = 0xC000013A + + _REQUEST_TIMEOUT = 10 + +@@ -620,7 +623,10 @@ def server_base_url(request): + + yield base_url + +- assert server.returncode == 0 ++ # NOTE(vytas): Starting with 0.29.0, Uvicorn will propagate signal ++ # values into the return code (which is a good practice in Unix); ++ # see also https://github.com/encode/uvicorn/pull/1600 ++ assert server.returncode in (0, -signal.SIGTERM, _STATUS_CONTROL_C_EXIT) + + break + +diff --git a/tests/asgi/test_scope.py b/tests/asgi/test_scope.py +index bb60ed0e7..e368f6576 100644 +--- a/tests/asgi/test_scope.py ++++ b/tests/asgi/test_scope.py +@@ -70,7 +70,7 @@ def test_supported_asgi_version(version, supported): + resp_event_collector = testing.ASGIResponseEventCollector() + + async def task(): +- coro = asyncio.get_event_loop().create_task( ++ coro = asyncio.get_running_loop().create_task( + app(scope, req_event_emitter, resp_event_collector) + ) + +@@ -142,7 +142,7 @@ def test_lifespan_scope_default_version(): + scope = {'type': 'lifespan'} + + async def t(): +- t = asyncio.get_event_loop().create_task( ++ t = asyncio.get_running_loop().create_task( + app(scope, req_event_emitter, resp_event_collector) + ) + +@@ -196,7 +196,7 @@ def test_lifespan_scope_version(spec_version, supported): + return + + async def t(): +- t = asyncio.get_event_loop().create_task( ++ t = asyncio.get_running_loop().create_task( + app(scope, req_event_emitter, resp_event_collector) + ) + +diff --git a/tests/dump_asgi.py b/tests/dump_asgi.py +index 0742a3ca0..0dfdb4b0a 100644 +--- a/tests/dump_asgi.py ++++ b/tests/dump_asgi.py +@@ -23,5 +23,5 @@ async def app(scope, receive, send): + } + ) + +- loop = asyncio.get_event_loop() ++ loop = asyncio.get_running_loop() + loop.create_task(_say_hi())