From 4a6f2b63d7ad5907b3d64f8e4d318e7d59b4dd5f Mon Sep 17 00:00:00 2001 From: hashlash Date: Sat, 21 Mar 2020 03:20:48 +0700 Subject: [PATCH] Fixed #31380 -- Added deployment system check for DJANGO_ALLOW_ASYNC_UNSAFE environment variable. --- django/core/checks/__init__.py | 1 + django/core/checks/async_checks.py | 16 ++++++++++++++++ django/core/checks/registry.py | 1 + docs/ref/checks.txt | 16 ++++++++++++++++ tests/check_framework/test_async_checks.py | 15 +++++++++++++++ 5 files changed, 49 insertions(+) create mode 100644 django/core/checks/async_checks.py create mode 100644 tests/check_framework/test_async_checks.py diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py index ededae38ba..37b531fe5f 100644 --- a/django/core/checks/__init__.py +++ b/django/core/checks/__init__.py @@ -5,6 +5,7 @@ from .messages import ( from .registry import Tags, register, run_checks, tag_exists # Import these to force registration of checks +import django.core.checks.async_checks # NOQA isort:skip import django.core.checks.caches # NOQA isort:skip import django.core.checks.database # NOQA isort:skip import django.core.checks.model_checks # NOQA isort:skip diff --git a/django/core/checks/async_checks.py b/django/core/checks/async_checks.py new file mode 100644 index 0000000000..fbb5267358 --- /dev/null +++ b/django/core/checks/async_checks.py @@ -0,0 +1,16 @@ +import os + +from . import Error, Tags, register + +E001 = Error( + 'You should not set the DJANGO_ALLOW_ASYNC_UNSAFE environment variable in ' + 'deployment. This disables async safety protection.', + id='async.E001', +) + + +@register(Tags.async_support, deploy=True) +def check_async_unsafe(app_configs, **kwargs): + if os.environ.get('DJANGO_ALLOW_ASYNC_UNSAFE'): + return [E001] + return [] diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py index 74359db586..bf83c51799 100644 --- a/django/core/checks/registry.py +++ b/django/core/checks/registry.py @@ -8,6 +8,7 @@ class Tags: Built-in tags for internal checks. """ admin = 'admin' + async_support = 'async_support' caches = 'caches' compatibility = 'compatibility' database = 'database' diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 2ebaf5201f..ec3735598a 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -74,6 +74,7 @@ Builtin tags Django's system checks are organized using the following tags: * ``admin``: Checks of any admin site declarations. +* ``async_support``: Checks asynchronous-related configuration. * ``caches``: Checks cache related configuration. * ``compatibility``: Flags potential problems with version upgrades. * ``database``: Checks database-related configuration issues. Database checks @@ -91,6 +92,10 @@ Django's system checks are organized using the following tags: Some checks may be registered with multiple tags. +.. versionchanged:: 3.1 + + The ``async_support`` tag was added. + .. versionchanged:: 3.1 The ``database`` checks are now run only for database aliases specified @@ -99,6 +104,17 @@ Some checks may be registered with multiple tags. Core system checks ================== +Asynchronous support +-------------------- + +.. versionadded:: 3.1 + +The following checks verify your setup for :doc:`/topics/async`: + +* **async.E001**: You should not set the ``DJANGO_ALLOW_ASYNC_UNSAFE`` + environment variable in deployment. This disables :ref:`async safety + protection `. + Backwards compatibility ----------------------- diff --git a/tests/check_framework/test_async_checks.py b/tests/check_framework/test_async_checks.py new file mode 100644 index 0000000000..fa7f840172 --- /dev/null +++ b/tests/check_framework/test_async_checks.py @@ -0,0 +1,15 @@ +import os +from unittest import mock + +from django.core.checks.async_checks import E001, check_async_unsafe +from django.test import SimpleTestCase + + +class AsyncCheckTests(SimpleTestCase): + @mock.patch.dict(os.environ, {'DJANGO_ALLOW_ASYNC_UNSAFE': ''}) + def test_no_allowed_async_unsafe(self): + self.assertEqual(check_async_unsafe(None), []) + + @mock.patch.dict(os.environ, {'DJANGO_ALLOW_ASYNC_UNSAFE': 'true'}) + def test_allowed_async_unsafe_set(self): + self.assertEqual(check_async_unsafe(None), [E001])