diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/asgiref/compatibility.py')
-rw-r--r-- | .venv/lib/python3.12/site-packages/asgiref/compatibility.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/asgiref/compatibility.py b/.venv/lib/python3.12/site-packages/asgiref/compatibility.py new file mode 100644 index 00000000..3a2a63e6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/asgiref/compatibility.py @@ -0,0 +1,48 @@ +import inspect + +from .sync import iscoroutinefunction + + +def is_double_callable(application): + """ + Tests to see if an application is a legacy-style (double-callable) application. + """ + # Look for a hint on the object first + if getattr(application, "_asgi_single_callable", False): + return False + if getattr(application, "_asgi_double_callable", False): + return True + # Uninstanted classes are double-callable + if inspect.isclass(application): + return True + # Instanted classes depend on their __call__ + if hasattr(application, "__call__"): + # We only check to see if its __call__ is a coroutine function - + # if it's not, it still might be a coroutine function itself. + if iscoroutinefunction(application.__call__): + return False + # Non-classes we just check directly + return not iscoroutinefunction(application) + + +def double_to_single_callable(application): + """ + Transforms a double-callable ASGI application into a single-callable one. + """ + + async def new_application(scope, receive, send): + instance = application(scope) + return await instance(receive, send) + + return new_application + + +def guarantee_single_callable(application): + """ + Takes either a single- or double-callable application and always returns it + in single-callable style. Use this to add backwards compatibility for ASGI + 2.0 applications to your server/test harness/etc. + """ + if is_double_callable(application): + application = double_to_single_callable(application) + return application |