From 7fe1d62f54997a33e2f7ad428c51b7978f2c1f9d Mon Sep 17 00:00:00 2001 From: Rooyal <49204095+Royalflamejlh@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:09:32 -0500 Subject: [PATCH] Fix ASGI compatibliity on Python 3.12 (#911) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Adam Johnson --- CHANGELOG.rst | 4 ++++ pyproject.toml | 1 + requirements/py310-django32.txt | 4 +++- requirements/py310-django40.txt | 4 +++- requirements/py310-django41.txt | 4 +++- requirements/py310-django42.txt | 4 +++- requirements/py310-django50.txt | 4 +++- requirements/py311-django41.txt | 4 +++- requirements/py311-django42.txt | 4 +++- requirements/py311-django50.txt | 4 +++- requirements/py312-django42.txt | 4 +++- requirements/py312-django50.txt | 4 +++- requirements/py38-django32.txt | 4 +++- requirements/py38-django40.txt | 4 +++- requirements/py38-django41.txt | 4 +++- requirements/py38-django42.txt | 4 +++- requirements/py39-django32.txt | 4 +++- requirements/py39-django40.txt | 4 +++- requirements/py39-django41.txt | 4 +++- requirements/py39-django42.txt | 4 +++- requirements/requirements.in | 1 + src/corsheaders/middleware.py | 16 ++++++++-------- 22 files changed, 68 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8bce595e..675b8ce2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,10 @@ Changelog ========= +* Fixed ASGI compatibility on Python 3.12. + + Thanks to Adrian Capitanu for the report in `Issue #908 `__ and Rooyal in `PR #911 `__. + 4.3.0 (2023-10-11) ------------------ diff --git a/pyproject.toml b/pyproject.toml index 938bbb39..06db9968 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ + "asgiref>=3.6", "Django>=3.2", ] [project.urls] diff --git a/requirements/py310-django32.txt b/requirements/py310-django32.txt index 63bbd862..34af2e0c 100644 --- a/requirements/py310-django32.txt +++ b/requirements/py310-django32.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py310-django40.txt b/requirements/py310-django40.txt index e75de6e8..e34cbdf5 100644 --- a/requirements/py310-django40.txt +++ b/requirements/py310-django40.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py310-django41.txt b/requirements/py310-django41.txt index f9104182..513a8abc 100644 --- a/requirements/py310-django41.txt +++ b/requirements/py310-django41.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py310-django42.txt b/requirements/py310-django42.txt index e48482b0..c1304536 100644 --- a/requirements/py310-django42.txt +++ b/requirements/py310-django42.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py310-django50.txt b/requirements/py310-django50.txt index 267c2ccb..8bc041e6 100644 --- a/requirements/py310-django50.txt +++ b/requirements/py310-django50.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py311-django41.txt b/requirements/py311-django41.txt index 879af001..1cef4a3b 100644 --- a/requirements/py311-django41.txt +++ b/requirements/py311-django41.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py311-django42.txt b/requirements/py311-django42.txt index 6259e49f..f7199f06 100644 --- a/requirements/py311-django42.txt +++ b/requirements/py311-django42.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py311-django50.txt b/requirements/py311-django50.txt index 1c50f092..b45de2d9 100644 --- a/requirements/py311-django50.txt +++ b/requirements/py311-django50.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py312-django42.txt b/requirements/py312-django42.txt index 5cf6c94a..1229730c 100644 --- a/requirements/py312-django42.txt +++ b/requirements/py312-django42.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py312-django50.txt b/requirements/py312-django50.txt index 3025863d..df8a2951 100644 --- a/requirements/py312-django50.txt +++ b/requirements/py312-django50.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py38-django32.txt b/requirements/py38-django32.txt index 852a995a..ecd1935f 100644 --- a/requirements/py38-django32.txt +++ b/requirements/py38-django32.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py38-django40.txt b/requirements/py38-django40.txt index f1a906c1..c7386b68 100644 --- a/requirements/py38-django40.txt +++ b/requirements/py38-django40.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django backports-zoneinfo==0.2.1 \ --hash=sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf \ --hash=sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328 \ diff --git a/requirements/py38-django41.txt b/requirements/py38-django41.txt index d3643d02..0459cc44 100644 --- a/requirements/py38-django41.txt +++ b/requirements/py38-django41.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django backports-zoneinfo==0.2.1 \ --hash=sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf \ --hash=sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328 \ diff --git a/requirements/py38-django42.txt b/requirements/py38-django42.txt index ec99069e..c0e46d8d 100644 --- a/requirements/py38-django42.txt +++ b/requirements/py38-django42.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django backports-zoneinfo==0.2.1 \ --hash=sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf \ --hash=sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328 \ diff --git a/requirements/py39-django32.txt b/requirements/py39-django32.txt index 2256b2ff..50134cd1 100644 --- a/requirements/py39-django32.txt +++ b/requirements/py39-django32.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py39-django40.txt b/requirements/py39-django40.txt index b033647b..23f80df4 100644 --- a/requirements/py39-django40.txt +++ b/requirements/py39-django40.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py39-django41.txt b/requirements/py39-django41.txt index bb715e6e..e038c74e 100644 --- a/requirements/py39-django41.txt +++ b/requirements/py39-django41.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/py39-django42.txt b/requirements/py39-django42.txt index 8e5eb9e1..f4530594 100644 --- a/requirements/py39-django42.txt +++ b/requirements/py39-django42.txt @@ -7,7 +7,9 @@ asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed - # via django + # via + # -r requirements.in + # django coverage[toml]==7.3.2 \ --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ diff --git a/requirements/requirements.in b/requirements/requirements.in index 443911a0..ccc2546a 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -1,3 +1,4 @@ +asgiref>=3.6 coverage[toml] django pytest diff --git a/src/corsheaders/middleware.py b/src/corsheaders/middleware.py index 2136d1e9..e97fe7de 100644 --- a/src/corsheaders/middleware.py +++ b/src/corsheaders/middleware.py @@ -1,12 +1,13 @@ from __future__ import annotations -import asyncio import re from typing import Awaitable from typing import Callable from urllib.parse import SplitResult from urllib.parse import urlsplit +from asgiref.sync import iscoroutinefunction +from asgiref.sync import markcoroutinefunction from django.http import HttpRequest from django.http import HttpResponse from django.http.response import HttpResponseBase @@ -37,19 +38,18 @@ def __init__( ), ) -> None: self.get_response = get_response - if asyncio.iscoroutinefunction(self.get_response): + self.async_mode = iscoroutinefunction(self.get_response) + + if self.async_mode: # 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 # type: ignore [attr-defined] - ) - else: - self._is_coroutine = None + markcoroutinefunction(self) def __call__( self, request: HttpRequest ) -> HttpResponseBase | Awaitable[HttpResponseBase]: - if self._is_coroutine: + if self.async_mode: return self.__acall__(request) response: HttpResponseBase | None = self.check_preflight(request) if response is None: