33from abc import ABC , abstractmethod
44from collections import OrderedDict , deque
55from collections .abc import (
6+ AsyncGenerator ,
67 AsyncIterator ,
78 Awaitable ,
89 Callable ,
910 Collection ,
11+ Generator ,
1012 Iterable ,
1113 Iterator ,
1214 Mapping ,
@@ -360,6 +362,14 @@ def get_default(cls) -> Priority:
360362
361363type PriorityStr = Literal ["low" , "high" ]
362364
365+ type ContextManagerLikeRecipe [** P , T ] = (
366+ Callable [P , ContextManager [T ]] | Callable [P , AsyncContextManager [T ]]
367+ )
368+ type GeneratorRecipe [** P , T ] = (
369+ Callable [P , Generator [T , Any , Any ]] | Callable [P , AsyncGenerator [T , Any ]]
370+ )
371+ type Recipe [** P , T ] = Callable [P , T ] | Callable [P , Awaitable [T ]]
372+
363373
364374@dataclass (eq = False , frozen = True , slots = True )
365375class Module (Broker , EventListener ):
@@ -411,7 +421,7 @@ def __brokers(self) -> Iterator[Broker]:
411421
412422 def injectable [** P , T ](
413423 self ,
414- wrapped : Callable [P , T ] | Callable [ P , Awaitable [ T ] ] | None = None ,
424+ wrapped : Recipe [P , T ] | None = None ,
415425 / ,
416426 * ,
417427 cls : InjectableFactory [T ] = SimpleInjectable ,
@@ -420,9 +430,7 @@ def injectable[**P, T](
420430 on : TypeInfo [T ] = (),
421431 mode : Mode | ModeStr = Mode .get_default (),
422432 ) -> Any :
423- def decorator (
424- wp : Callable [P , T ] | Callable [P , Awaitable [T ]],
425- ) -> Callable [P , T ] | Callable [P , Awaitable [T ]]:
433+ def decorator (wp : Recipe [P , T ]) -> Recipe [P , T ]:
426434 factory = extract_caller (self .make_injected_function (wp ) if inject else wp )
427435 hints = on if ignore_type_hint else (wp , on )
428436 updater = Updater (
@@ -447,23 +455,10 @@ def scoped[**P, T](
447455 mode : Mode | ModeStr = Mode .get_default (),
448456 ) -> Any :
449457 def decorator (
450- wrapped : Callable [P , T ]
451- | Callable [P , Awaitable [T ]]
452- | Callable [P , Iterator [T ]]
453- | Callable [P , AsyncIterator [T ]],
454- ) -> (
455- Callable [P , T ]
456- | Callable [P , Awaitable [T ]]
457- | Callable [P , Iterator [T ]]
458- | Callable [P , AsyncIterator [T ]]
459- ):
458+ wrapped : Recipe [P , T ] | GeneratorRecipe [P , T ],
459+ ) -> Recipe [P , T ] | GeneratorRecipe [P , T ]:
460460 injectable_class : Callable [[Caller [P , Any ], str ], Injectable [T ]]
461- wrapper : (
462- Callable [P , T ]
463- | Callable [P , Awaitable [T ]]
464- | Callable [P , ContextManager [T ]]
465- | Callable [P , AsyncContextManager [T ]]
466- )
461+ wrapper : Recipe [P , T ] | ContextManagerLikeRecipe [P , T ]
467462
468463 if isasyncgenfunction (wrapped ):
469464 hint = get_yield_hint (wrapped )
@@ -588,6 +583,18 @@ def listen() -> None:
588583
589584 return SyncInjectedFunction (metadata )
590585
586+ def make_async_factory [T ](
587+ self ,
588+ wrapped : type [T ],
589+ / ,
590+ threadsafe : bool = False ,
591+ ) -> Callable [..., Awaitable [T ]]:
592+ factory : InjectedFunction [..., T ] = self .make_injected_function (
593+ wrapped ,
594+ threadsafe ,
595+ )
596+ return factory .__inject_metadata__ .acall
597+
591598 async def afind_instance [T ](self , cls : InputType [T ]) -> T :
592599 injectable = self [cls ]
593600 return await injectable .aget_instance ()
0 commit comments