@@ -26,19 +26,41 @@ def _restore_context(context):
2626 cvar .set (context .get (cvar ))
2727
2828
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 # type: ignore
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+
2951def _iscoroutinefunction_or_partial (func : Any ) -> bool :
3052 # Python < 3.8 does not correctly determine partially wrapped
3153 # coroutine functions are coroutine functions, hence the need for
3254 # this to exist. Code taken from CPython.
3355 if sys .version_info >= (3 , 8 ):
34- return asyncio . iscoroutinefunction (func )
56+ return iscoroutinefunction (func )
3557 else :
3658 while inspect .ismethod (func ):
3759 func = func .__func__
3860 while isinstance (func , functools .partial ):
3961 func = func .func
4062
41- return asyncio . iscoroutinefunction (func )
63+ return iscoroutinefunction (func )
4264
4365
4466class ThreadSensitiveContext :
@@ -356,7 +378,7 @@ def __init__(
356378 self .func = func
357379 functools .update_wrapper (self , func )
358380 self ._thread_sensitive = thread_sensitive
359- self . _is_coroutine = asyncio . coroutines . _is_coroutine # type: ignore
381+ markcoroutinefunction ( self )
360382 if thread_sensitive and executor is not None :
361383 raise TypeError ("executor must not be set when thread_sensitive is True" )
362384 self ._executor = executor
0 commit comments