diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2022-12-20 11:10:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-20 11:10:48 +0100 |
| commit | 32d70b2f55b1f74736fd11bc8efce890ad5fa2f0 (patch) | |
| tree | d88822bb2391e7cf4fdbda59b9f222839aeb7e93 /django | |
| parent | a09d39f28609c707a62dbbbdc4e55489fae1631f (diff) | |
Refs #34118 -- Adopted asgiref coroutine detection shims.
Thanks to Mariusz Felisiak for review.
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/handlers/base.py | 12 | ||||
| -rw-r--r-- | django/core/handlers/exception.py | 5 | ||||
| -rw-r--r-- | django/test/testcases.py | 5 | ||||
| -rw-r--r-- | django/test/utils.py | 5 | ||||
| -rw-r--r-- | django/utils/deprecation.py | 11 | ||||
| -rw-r--r-- | django/views/generic/base.py | 9 |
6 files changed, 22 insertions, 25 deletions
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index a934659186..8911543d4e 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -2,7 +2,7 @@ import asyncio import logging import types -from asgiref.sync import async_to_sync, sync_to_async +from asgiref.sync import async_to_sync, iscoroutinefunction, sync_to_async from django.conf import settings from django.core.exceptions import ImproperlyConfigured, MiddlewareNotUsed @@ -119,7 +119,7 @@ class BaseHandler: - Asynchronous methods are left alone """ if method_is_async is None: - method_is_async = asyncio.iscoroutinefunction(method) + method_is_async = iscoroutinefunction(method) if debug and not name: name = name or "method %s()" % method.__qualname__ if is_async: @@ -191,7 +191,7 @@ class BaseHandler: if response is None: wrapped_callback = self.make_view_atomic(callback) # If it is an asynchronous view, run it in a subthread. - if asyncio.iscoroutinefunction(wrapped_callback): + if iscoroutinefunction(wrapped_callback): wrapped_callback = async_to_sync(wrapped_callback) try: response = wrapped_callback(request, *callback_args, **callback_kwargs) @@ -245,7 +245,7 @@ class BaseHandler: if response is None: wrapped_callback = self.make_view_atomic(callback) # If it is a synchronous view, run it in a subthread - if not asyncio.iscoroutinefunction(wrapped_callback): + if not iscoroutinefunction(wrapped_callback): wrapped_callback = sync_to_async( wrapped_callback, thread_sensitive=True ) @@ -278,7 +278,7 @@ class BaseHandler: % (middleware_method.__self__.__class__.__name__,), ) try: - if asyncio.iscoroutinefunction(response.render): + if iscoroutinefunction(response.render): response = await response.render() else: response = await sync_to_async( @@ -346,7 +346,7 @@ class BaseHandler: non_atomic_requests = getattr(view, "_non_atomic_requests", set()) for alias, settings_dict in connections.settings.items(): if settings_dict["ATOMIC_REQUESTS"] and alias not in non_atomic_requests: - if asyncio.iscoroutinefunction(view): + if iscoroutinefunction(view): raise RuntimeError( "You cannot use ATOMIC_REQUESTS with async views." ) diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py index 79577c2d0a..a0b1ba678a 100644 --- a/django/core/handlers/exception.py +++ b/django/core/handlers/exception.py @@ -1,9 +1,8 @@ -import asyncio import logging import sys from functools import wraps -from asgiref.sync import sync_to_async +from asgiref.sync import iscoroutinefunction, sync_to_async from django.conf import settings from django.core import signals @@ -34,7 +33,7 @@ def convert_exception_to_response(get_response): no middleware leaks an exception and that the next middleware in the stack can rely on getting a response instead of an exception. """ - if asyncio.iscoroutinefunction(get_response): + if iscoroutinefunction(get_response): @wraps(get_response) async def inner(request): diff --git a/django/test/testcases.py b/django/test/testcases.py index c78c2300a7..090a31e7c4 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1,4 +1,3 @@ -import asyncio import difflib import inspect import json @@ -26,7 +25,7 @@ from urllib.parse import ( ) from urllib.request import url2pathname -from asgiref.sync import async_to_sync +from asgiref.sync import async_to_sync, iscoroutinefunction from django.apps import apps from django.conf import settings @@ -401,7 +400,7 @@ class SimpleTestCase(unittest.TestCase): ) # Convert async test methods. - if asyncio.iscoroutinefunction(testMethod): + if iscoroutinefunction(testMethod): setattr(self, self._testMethodName, async_to_sync(testMethod)) if not skipped: diff --git a/django/test/utils.py b/django/test/utils.py index 2b2b92c593..5e5649b0ac 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -1,4 +1,3 @@ -import asyncio import collections import logging import os @@ -14,6 +13,8 @@ from types import SimpleNamespace from unittest import TestCase, skipIf, skipUnless from xml.dom.minidom import Node, parseString +from asgiref.sync import iscoroutinefunction + from django.apps import apps from django.apps.registry import Apps from django.conf import UserSettingsHolder, settings @@ -440,7 +441,7 @@ class TestContextDecorator: raise TypeError("Can only decorate subclasses of unittest.TestCase") def decorate_callable(self, func): - if asyncio.iscoroutinefunction(func): + if iscoroutinefunction(func): # If the inner function is an async function, we must execute async # as well so that the `with` statement executes at the right time. @wraps(func) diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index caed5b25d4..19379dfe58 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -1,8 +1,7 @@ -import asyncio import inspect import warnings -from asgiref.sync import sync_to_async +from asgiref.sync import iscoroutinefunction, markcoroutinefunction, sync_to_async class RemovedInDjango50Warning(DeprecationWarning): @@ -120,16 +119,14 @@ class MiddlewareMixin: If get_response is a coroutine function, turns us into async mode so a thread is not consumed during a whole request. """ - if asyncio.iscoroutinefunction(self.get_response): + if iscoroutinefunction(self.get_response): # Mark the class as async-capable, but do the actual switch # inside __call__ to avoid swapping out dunder methods - self._is_coroutine = asyncio.coroutines._is_coroutine - else: - self._is_coroutine = None + markcoroutinefunction(self) def __call__(self, request): # Exit out to async mode, if needed - if self._is_coroutine: + if iscoroutinefunction(self): return self.__acall__(request) response = None if hasattr(self, "process_request"): diff --git a/django/views/generic/base.py b/django/views/generic/base.py index 3a3afb0c73..8f8f9397e8 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -1,6 +1,7 @@ -import asyncio import logging +from asgiref.sync import iscoroutinefunction, markcoroutinefunction + from django.core.exceptions import ImproperlyConfigured from django.http import ( HttpResponse, @@ -68,8 +69,8 @@ class View: ] if not handlers: return False - is_async = asyncio.iscoroutinefunction(handlers[0]) - if not all(asyncio.iscoroutinefunction(h) == is_async for h in handlers[1:]): + is_async = iscoroutinefunction(handlers[0]) + if not all(iscoroutinefunction(h) == is_async for h in handlers[1:]): raise ImproperlyConfigured( f"{cls.__qualname__} HTTP handlers must either be all sync or all " "async." @@ -117,7 +118,7 @@ class View: # Mark the callback if the view class is async. if cls.view_is_async: - view._is_coroutine = asyncio.coroutines._is_coroutine + markcoroutinefunction(view) return view |
