summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaterina Vaartis <vaartis@kotobank.ch>2021-05-20 22:48:37 +0300
committerMichał Górny <mgorny@gentoo.org>2021-05-20 22:10:58 +0200
commitffad4d6fdd33979f972594f1be9155a81a78a769 (patch)
tree423cab0109822ff96bb4b86a54e36b38b973d784 /dev-python/asgiref
parentdev-db/postgresql: Add 14_beta1 (diff)
downloadgentoo-ffad4d6fdd33979f972594f1be9155a81a78a769.tar.gz
gentoo-ffad4d6fdd33979f972594f1be9155a81a78a769.tar.bz2
gentoo-ffad4d6fdd33979f972594f1be9155a81a78a769.zip
dev-python/asgiref: Bump to python 3.10 with a patch for warnings
Upstream PR: https://github.com/django/asgiref/pull/262 Signed-off-by: Ekaterina Vaartis <vaartis@kotobank.ch> Signed-off-by: Michał Górny <mgorny@gentoo.org>
Diffstat (limited to 'dev-python/asgiref')
-rw-r--r--dev-python/asgiref/asgiref-3.3.4.ebuild7
-rw-r--r--dev-python/asgiref/files/asgiref-3.3.4-py310-warnings.patch235
2 files changed, 241 insertions, 1 deletions
diff --git a/dev-python/asgiref/asgiref-3.3.4.ebuild b/dev-python/asgiref/asgiref-3.3.4.ebuild
index e32555868e8a..709bb95bb8f6 100644
--- a/dev-python/asgiref/asgiref-3.3.4.ebuild
+++ b/dev-python/asgiref/asgiref-3.3.4.ebuild
@@ -3,7 +3,7 @@
EAPI=7
-PYTHON_COMPAT=( python3_{7..9} pypy3 )
+PYTHON_COMPAT=( python3_{7..10} pypy3 )
inherit distutils-r1
DESCRIPTION="ASGI utilities (successor to WSGI)"
@@ -24,4 +24,9 @@ RDEPEND="
BDEPEND="
test? ( dev-python/pytest-asyncio[${PYTHON_USEDEP}] )"
+PATCHES=(
+ # Provided to upstream: https://github.com/django/asgiref/pull/262
+ "${FILESDIR}/${P}-py310-warnings.patch"
+)
+
distutils_enable_tests pytest
diff --git a/dev-python/asgiref/files/asgiref-3.3.4-py310-warnings.patch b/dev-python/asgiref/files/asgiref-3.3.4-py310-warnings.patch
new file mode 100644
index 000000000000..1cd017ddfbde
--- /dev/null
+++ b/dev-python/asgiref/files/asgiref-3.3.4-py310-warnings.patch
@@ -0,0 +1,235 @@
+From 0c9e989f18b99ea24a1fb3ea2c8a66fd295c2178 Mon Sep 17 00:00:00 2001
+From: Ekaterina Vaartis <vaartis@kotobank.ch>
+Date: Thu, 20 May 2021 19:44:15 +0300
+Subject: [PATCH] Fix deprecation warnings for python 3.10
+
+asyncio.get_event_loop was marked as deprecated, the documnetation
+now refers to asyncio.get_running_loop([1])
+
+asyncio.ensure_future issues a deprecation warning if there is no
+running event loop([2]), so use asyncio.run which creates and destroys the
+loop itself
+
+asyncio.gather issues a warning if run outside of event
+loop (i.e. there is no running event loop)([3]), so wrap it into an
+async def
+
+explicit passing of coroutine objects to asyncio.wait is deprecated
+since 3.8([4]), so wrap them in asyncio.create_task
+
+plus, add 3.10 to tox.ini
+
+[1]: https://docs.python.org/3.10/library/asyncio-eventloop.html#asyncio.get_event_loop
+[2]: https://docs.python.org/3.10/library/asyncio-future.html#asyncio.ensure_future
+[3]: https://docs.python.org/3.10/library/asyncio-task.html#asyncio.gather
+[4]: https://docs.python.org/3.10/library/asyncio-task.html#asyncio.wait
+---
+ asgiref/compatibility.py | 14 ++++++++++++++
+ asgiref/server.py | 8 ++++----
+ asgiref/sync.py | 15 ++++++++++-----
+ tests/test_sync.py | 19 ++++++++++++++-----
+ tests/test_sync_contextvars.py | 3 ++-
+ tox.ini | 2 +-
+ 6 files changed, 45 insertions(+), 16 deletions(-)
+
+diff --git a/asgiref/compatibility.py b/asgiref/compatibility.py
+index eccaee0..614b2e6 100644
+--- a/asgiref/compatibility.py
++++ b/asgiref/compatibility.py
+@@ -1,5 +1,6 @@
+ import asyncio
+ import inspect
++import sys
+
+
+ def is_double_callable(application):
+@@ -45,3 +46,16 @@ def guarantee_single_callable(application):
+ if is_double_callable(application):
+ application = double_to_single_callable(application)
+ return application
++
++
++if sys.version_info >= (3, 7):
++ # these were introduced in 3.7
++ get_running_loop = asyncio.get_running_loop
++ run_future = asyncio.run
++ create_task = asyncio.create_task
++else:
++ # marked as deprecated in 3.10, did not exist before 3.7
++ get_running_loop = asyncio.get_event_loop
++ run_future = asyncio.ensure_future
++ # does nothing, this is fine for <3.7
++ create_task = lambda task: task
+diff --git a/asgiref/server.py b/asgiref/server.py
+index f975f78..fb1c394 100644
+--- a/asgiref/server.py
++++ b/asgiref/server.py
+@@ -3,7 +3,7 @@ import logging
+ import time
+ import traceback
+
+-from .compatibility import guarantee_single_callable
++from .compatibility import get_running_loop, guarantee_single_callable, run_future
+
+ logger = logging.getLogger(__name__)
+
+@@ -56,7 +56,7 @@ class StatelessServer:
+ """
+ Runs the asyncio event loop with our handler loop.
+ """
+- event_loop = asyncio.get_event_loop()
++ event_loop = get_running_loop()
+ asyncio.ensure_future(self.application_checker())
+ try:
+ event_loop.run_until_complete(self.handle())
+@@ -88,12 +88,12 @@ class StatelessServer:
+ input_queue = asyncio.Queue()
+ application_instance = guarantee_single_callable(self.application)
+ # Run it, and stash the future for later checking
+- future = asyncio.ensure_future(
++ future = run_future(
+ application_instance(
+ scope=scope,
+ receive=input_queue.get,
+ send=lambda message: self.application_send(scope, message),
+- )
++ ),
+ )
+ self.application_instances[scope_id] = {
+ "input_queue": input_queue,
+diff --git a/asgiref/sync.py b/asgiref/sync.py
+index 6b87c7e..9476e66 100644
+--- a/asgiref/sync.py
++++ b/asgiref/sync.py
+@@ -9,6 +9,7 @@ import weakref
+ from concurrent.futures import Future, ThreadPoolExecutor
+ from typing import Any, Callable, Dict, Optional, Union
+
++from .compatibility import get_running_loop
+ from .current_thread_executor import CurrentThreadExecutor
+ from .local import Local
+
+@@ -132,7 +133,7 @@ class AsyncToSync:
+ self.main_event_loop = None
+ else:
+ try:
+- self.main_event_loop = asyncio.get_event_loop()
++ self.main_event_loop = get_running_loop()
+ except RuntimeError:
+ # There's no event loop in this thread. Look for the threadlocal if
+ # we're inside SyncToAsync
+@@ -151,7 +152,7 @@ class AsyncToSync:
+ def __call__(self, *args, **kwargs):
+ # You can't call AsyncToSync from a thread with a running event loop
+ try:
+- event_loop = asyncio.get_event_loop()
++ event_loop = get_running_loop()
+ except RuntimeError:
+ pass
+ else:
+@@ -238,7 +239,11 @@ class AsyncToSync:
+ tasks = asyncio.Task.all_tasks(loop)
+ for task in tasks:
+ task.cancel()
+- loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True))
++
++ async def gather():
++ await asyncio.gather(*tasks, return_exceptions=True)
++
++ loop.run_until_complete(gather())
+ for task in tasks:
+ if task.cancelled():
+ continue
+@@ -320,7 +325,7 @@ class SyncToAsync:
+
+ # If they've set ASGI_THREADS, update the default asyncio executor for now
+ if "ASGI_THREADS" in os.environ:
+- loop = asyncio.get_event_loop()
++ loop = get_running_loop()
+ loop.set_default_executor(
+ ThreadPoolExecutor(max_workers=int(os.environ["ASGI_THREADS"]))
+ )
+@@ -370,7 +375,7 @@ class SyncToAsync:
+ pass
+
+ async def __call__(self, *args, **kwargs):
+- loop = asyncio.get_event_loop()
++ loop = get_running_loop()
+
+ # Work out what thread to run the code in
+ if self._thread_sensitive:
+diff --git a/tests/test_sync.py b/tests/test_sync.py
+index cf0e0c5..8ed76a7 100644
+--- a/tests/test_sync.py
++++ b/tests/test_sync.py
+@@ -9,6 +9,7 @@ from unittest import TestCase
+
+ import pytest
+
++from asgiref.compatibility import create_task, get_running_loop
+ from asgiref.sync import ThreadSensitiveContext, async_to_sync, sync_to_async
+
+
+@@ -33,12 +34,17 @@ async def test_sync_to_async():
+ assert result == 42
+ assert end - start >= 1
+ # Set workers to 1, call it twice and make sure that works right
+- loop = asyncio.get_event_loop()
+- old_executor = loop._default_executor
++ loop = get_running_loop()
++ old_executor = loop._default_executor or ThreadPoolExecutor()
+ loop.set_default_executor(ThreadPoolExecutor(max_workers=1))
+ try:
+ start = time.monotonic()
+- await asyncio.wait([async_function(), async_function()])
++ await asyncio.wait(
++ [
++ create_task(async_function()),
++ create_task(async_function()),
++ ]
++ )
+ end = time.monotonic()
+ # It should take at least 2 seconds as there's only one worker.
+ assert end - start >= 2
+@@ -428,7 +434,7 @@ async def test_thread_sensitive_outside_async():
+ result["thread"] = threading.current_thread()
+
+ # Run it (in supposed parallel!)
+- await asyncio.wait([outer(result_1), inner(result_2)])
++ await asyncio.wait([create_task(outer(result_1)), create_task(inner(result_2))])
+
+ # They should not have run in the main thread, but in the same thread
+ assert result_1["thread"] != threading.current_thread()
+@@ -449,7 +455,10 @@ async def test_thread_sensitive_with_context_matches():
+ async with ThreadSensitiveContext():
+ # Run it (in supposed parallel!)
+ await asyncio.wait(
+- [store_thread_async(result_1), store_thread_async(result_2)]
++ [
++ create_task(store_thread_async(result_1)),
++ create_task(store_thread_async(result_2)),
++ ]
+ )
+
+ await fn()
+diff --git a/tests/test_sync_contextvars.py b/tests/test_sync_contextvars.py
+index b1027aa..9665bf9 100644
+--- a/tests/test_sync_contextvars.py
++++ b/tests/test_sync_contextvars.py
+@@ -4,6 +4,7 @@ import time
+
+ import pytest
+
++from asgiref.compatibility import create_task
+ from asgiref.sync import ThreadSensitiveContext, async_to_sync, sync_to_async
+
+ contextvars = pytest.importorskip("contextvars")
+@@ -25,7 +26,7 @@ async def test_thread_sensitive_with_context_different():
+ await store_thread(result)
+
+ # Run it (in true parallel!)
+- await asyncio.wait([fn(result_1), fn(result_2)])
++ await asyncio.wait([create_task(fn(result_1)), create_task(fn(result_2))])
+
+ # They should not have run in the main thread, and on different threads
+ assert result_1["thread"] != threading.current_thread()