util.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. from collections.abc import Callable, Coroutine
  2. from typing import TypeVar
  3. from ..types import Message, Context
  4. from .base import Injector, InjectorWithCleanup
  5. __all__ = [
  6. "Lazy",
  7. "MessageInjector",
  8. "ContextInjector",
  9. ]
  10. class MessageInjector(Injector[Message]):
  11. async def inject(self, message: Message, context: Context) -> Message:
  12. return message
  13. MessageInjector = MessageInjector()
  14. class ContextInjector(Injector[Context]):
  15. async def inject(self, message: Message, context: Context) -> Context:
  16. return context
  17. ContextInjector = ContextInjector()
  18. Dep = TypeVar("Dep")
  19. class Lazy(InjectorWithCleanup[Callable[[], Coroutine[None, None, Dep]]]):
  20. def __init__(self, deferred: Injector[Dep]):
  21. self.deferred = deferred
  22. async def inject(
  23. self, message: Message, context: Context
  24. ) -> Callable[[], Coroutine[None, None, Dep]]:
  25. class _Wrapper:
  26. def __init__(self, deferred):
  27. self._calculated = None
  28. async def call():
  29. if self._calculated is None:
  30. self._calculated = await deferred.inject(message, context)
  31. return self._calculated
  32. self._call = call
  33. def __call__(self):
  34. return self._call()
  35. return _Wrapper(self.deferred)
  36. async def cleanup(self, dep: Callable[[], Coroutine[None, None, Dep]]):
  37. if isinstance(self.deferred, InjectorWithCleanup) and dep._calculated is not None:
  38. await self.deferred.cleanup(dep._calculated)