Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

compatibility.py 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import inspect
  2. from .sync import iscoroutinefunction
  3. def is_double_callable(application):
  4. """
  5. Tests to see if an application is a legacy-style (double-callable) application.
  6. """
  7. # Look for a hint on the object first
  8. if getattr(application, "_asgi_single_callable", False):
  9. return False
  10. if getattr(application, "_asgi_double_callable", False):
  11. return True
  12. # Uninstanted classes are double-callable
  13. if inspect.isclass(application):
  14. return True
  15. # Instanted classes depend on their __call__
  16. if hasattr(application, "__call__"):
  17. # We only check to see if its __call__ is a coroutine function -
  18. # if it's not, it still might be a coroutine function itself.
  19. if iscoroutinefunction(application.__call__):
  20. return False
  21. # Non-classes we just check directly
  22. return not iscoroutinefunction(application)
  23. def double_to_single_callable(application):
  24. """
  25. Transforms a double-callable ASGI application into a single-callable one.
  26. """
  27. async def new_application(scope, receive, send):
  28. instance = application(scope)
  29. return await instance(receive, send)
  30. return new_application
  31. def guarantee_single_callable(application):
  32. """
  33. Takes either a single- or double-callable application and always returns it
  34. in single-callable style. Use this to add backwards compatibility for ASGI
  35. 2.0 applications to your server/test harness/etc.
  36. """
  37. if is_double_callable(application):
  38. application = double_to_single_callable(application)
  39. return application