diff options
author | Andrew Godwin <andrew@aeracode.org> | 2019-04-12 06:15:18 -0700 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-06-20 12:29:43 +0200 |
commit | a415ce70bef6d91036b00dd2c8544aed7aeeaaed (patch) | |
tree | 3583cef22e9b56d2ed52456ab586d9c47620bc51 /django/utils/asyncio.py | |
parent | cce47ff65a4dd3786c049ec14ee889e128ca7de9 (diff) | |
download | django-a415ce70bef6d91036b00dd2c8544aed7aeeaaed.tar.gz |
Fixed #30451 -- Added ASGI handler and coroutine-safety.
This adds an ASGI handler, asgi.py file for the default project layout,
a few async utilities and adds async-safety to many parts of Django.
Diffstat (limited to 'django/utils/asyncio.py')
-rw-r--r-- | django/utils/asyncio.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/django/utils/asyncio.py b/django/utils/asyncio.py new file mode 100644 index 0000000000..c4de04ba12 --- /dev/null +++ b/django/utils/asyncio.py @@ -0,0 +1,32 @@ +import asyncio +import functools + +from django.core.exceptions import SynchronousOnlyOperation + + +def async_unsafe(message): + """ + Decorator to mark functions as async-unsafe. Someone trying to access + the function while in an async context will get an error message. + """ + def decorator(func): + @functools.wraps(func) + def inner(*args, **kwargs): + # Detect a running event loop in this thread. + try: + event_loop = asyncio.get_event_loop() + except RuntimeError: + pass + else: + if event_loop.is_running(): + raise SynchronousOnlyOperation(message) + # Pass onwards. + return func(*args, **kwargs) + return inner + # If the message is actually a function, then be a no-arguments decorator. + if callable(message): + func = message + message = 'You cannot call this from an async context - use a thread or sync_to_async.' + return decorator(func) + else: + return decorator |