| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- # Includes work from:
- # Copyright (c) Django Software Foundation and individual contributors.
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without modification,
- # are permitted provided that the following conditions are met:
- #
- # 1. Redistributions of source code must retain the above copyright notice,
- # this list of conditions and the following disclaimer.
- #
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- #
- # 3. Neither the name of Django nor the names of its contributors may be used
- # to endorse or promote products derived from this software without
- # specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- from __future__ import annotations
- import asyncio
- import inspect
- from typing import TYPE_CHECKING, cast
- if TYPE_CHECKING:
- from asgiref.typing import (
- ASGI2Application,
- ASGI3Application,
- ASGIApplication,
- ASGIReceiveCallable,
- ASGISendCallable,
- Scope,
- )
- # Vendored from https://github.com/django/asgiref/blob/main/asgiref/compatibility.py
- if hasattr(inspect, "markcoroutinefunction"):
- iscoroutinefunction = inspect.iscoroutinefunction
- else:
- iscoroutinefunction = asyncio.iscoroutinefunction # type: ignore[assignment]
- def is_double_callable(application: ASGIApplication) -> bool:
- if getattr(application, "_asgi_single_callable", False):
- return False
- if getattr(application, "_asgi_double_callable", False):
- return True
- if inspect.isclass(application):
- return True
- if callable(application) and iscoroutinefunction(application.__call__):
- return False
- return not iscoroutinefunction(application)
- def double_to_single_callable(application: ASGI2Application) -> ASGI3Application:
- async def new_application(
- scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable
- ) -> None:
- instance = application(scope)
- return await instance(receive, send)
- return new_application
- def guarantee_single_callable(application: ASGIApplication) -> ASGI3Application:
- if is_double_callable(application):
- application = double_to_single_callable(cast("ASGI2Application", application))
- return cast("ASGI3Application", application)
|