@@ -26,19 +26,41 @@ def _restore_context(context):
26
26
cvar .set (context .get (cvar ))
27
27
28
28
29
+ # Python 3.12 deprecates asyncio.iscoroutinefunction() as an alias for
30
+ # inspect.iscoroutinefunction(), whilst also removing the _is_coroutine marker.
31
+ # The latter is replaced with the inspect.markcoroutinefunction decorator.
32
+ # Until 3.12 is the minimum supported Python version, provide a shim.
33
+ # Django 4.0 only supports 3.8+, so don't concern with the _or_partial backport.
34
+
35
+ # Type hint: should be generic: whatever T it takes it returns. (Same id)
36
+ def markcoroutinefunction (func : Any ) -> Any :
37
+ if hasattr (inspect , "markcoroutinefunction" ):
38
+ return inspect .markcoroutinefunction (func )
39
+ else :
40
+ func ._is_coroutine = asyncio .coroutines ._is_coroutine
41
+ return func
42
+
43
+
44
+ def iscoroutinefunction (func : Any ) -> bool :
45
+ if hasattr (inspect , "markcoroutinefunction" ):
46
+ return inspect .iscoroutinefunction (func )
47
+ else :
48
+ return asyncio .iscoroutinefunction (func )
49
+
50
+
29
51
def _iscoroutinefunction_or_partial (func : Any ) -> bool :
30
52
# Python < 3.8 does not correctly determine partially wrapped
31
53
# coroutine functions are coroutine functions, hence the need for
32
54
# this to exist. Code taken from CPython.
33
55
if sys .version_info >= (3 , 8 ):
34
- return asyncio . iscoroutinefunction (func )
56
+ return iscoroutinefunction (func )
35
57
else :
36
58
while inspect .ismethod (func ):
37
59
func = func .__func__
38
60
while isinstance (func , functools .partial ):
39
61
func = func .func
40
62
41
- return asyncio . iscoroutinefunction (func )
63
+ return iscoroutinefunction (func )
42
64
43
65
44
66
class ThreadSensitiveContext :
0 commit comments