11from __future__ import annotations
22
3- import asyncio
43from abc import ABC , abstractmethod
5- from collections import OrderedDict
4+ from collections import OrderedDict , deque
65from collections .abc import (
76 AsyncIterator ,
87 Awaitable ,
2625)
2726from inspect import signature as inspect_signature
2827from logging import Logger , getLogger
29- from queue import Empty , Queue
3028from types import MethodType
3129from typing import (
3230 Any ,
5048from injection ._core .common .event import Event , EventChannel , EventListener
5149from injection ._core .common .invertible import Invertible , SimpleInvertible
5250from injection ._core .common .key import new_short_key
53- from injection ._core .common .lazy import Lazy , LazyMapping
51+ from injection ._core .common .lazy import Lazy , alazy , lazy
5452from injection ._core .common .type import (
5553 InputType ,
5654 TypeInfo ,
@@ -296,6 +294,9 @@ def unlock(self) -> Self:
296294
297295 async def all_ready (self ) -> None :
298296 for injectable in self .__injectables :
297+ if injectable .is_locked :
298+ continue
299+
299300 await injectable .aget_instance ()
300301
301302 def add_listener (self , listener : EventListener ) -> Self :
@@ -511,7 +512,7 @@ def constant[T](
511512 mode : Mode | ModeStr = Mode .get_default (),
512513 ) -> Any :
513514 def decorator (wp : type [T ]) -> type [T ]:
514- lazy_instance = Lazy (wp )
515+ lazy_instance = lazy (wp )
515516 self .injectable (
516517 lambda : ~ lazy_instance ,
517518 ignore_type_hint = True ,
@@ -568,7 +569,7 @@ def make_injected_function[**P, T](
568569 def make_injected_function (self , wrapped , / ): # type: ignore[no-untyped-def]
569570 metadata = InjectMetadata (wrapped )
570571
571- @metadata .on_setup
572+ @metadata .task
572573 def listen () -> None :
573574 metadata .update (self )
574575 self .add_listener (metadata )
@@ -646,12 +647,10 @@ def aget_lazy_instance[T](
646647
647648 def aget_lazy_instance (self , cls , default = None , * , cache = False ): # type: ignore[no-untyped-def]
648649 if cache :
649- coroutine = self .aget_instance (cls , default )
650- return asyncio .ensure_future (coroutine )
650+ return alazy (lambda : self .aget_instance (cls , default ))
651651
652652 function = self .make_injected_function (lambda instance = default : instance )
653- metadata = function .__inject_metadata__
654- metadata .set_owner (cls )
653+ metadata = function .__inject_metadata__ .set_owner (cls )
655654 return SimpleAwaitable (metadata .acall )
656655
657656 @overload
@@ -674,11 +673,10 @@ def get_lazy_instance[T](
674673
675674 def get_lazy_instance (self , cls , default = None , * , cache = False ): # type: ignore[no-untyped-def]
676675 if cache :
677- return Lazy (lambda : self .get_instance (cls , default ))
676+ return lazy (lambda : self .get_instance (cls , default ))
678677
679678 function = self .make_injected_function (lambda instance = default : instance )
680- metadata = function .__inject_metadata__
681- metadata .set_owner (cls )
679+ metadata = function .__inject_metadata__ .set_owner (cls )
682680 return SimpleInvertible (metadata .call )
683681
684682 def update [T ](self , updater : Updater [T ]) -> Self :
@@ -832,10 +830,7 @@ def mod(name: str | None = None, /) -> Module:
832830
833831@dataclass (repr = False , frozen = True , slots = True )
834832class Dependencies :
835- mapping : Mapping [str , Injectable [Any ]]
836-
837- def __bool__ (self ) -> bool :
838- return bool (self .mapping )
833+ lazy_mapping : Lazy [Mapping [str , Injectable [Any ]]]
839834
840835 def __iter__ (self ) -> Iterator [tuple [str , Any ]]:
841836 for name , injectable in self .mapping .items ():
@@ -849,10 +844,11 @@ async def __aiter__(self) -> AsyncIterator[tuple[str, Any]]:
849844
850845 @property
851846 def are_resolved (self ) -> bool :
852- if isinstance (self .mapping , LazyMapping ) and not self .mapping .is_set :
853- return False
847+ return self .lazy_mapping .is_set
854848
855- return bool (self )
849+ @property
850+ def mapping (self ) -> Mapping [str , Injectable [Any ]]:
851+ return ~ self .lazy_mapping
856852
857853 async def aget_arguments (self ) -> dict [str , Any ]:
858854 return {key : value async for key , value in self }
@@ -861,12 +857,13 @@ def get_arguments(self) -> dict[str, Any]:
861857 return dict (self )
862858
863859 @classmethod
864- def from_mapping (cls , mapping : Mapping [str , Injectable [Any ]]) -> Self :
865- return cls (mapping )
860+ def from_iterable (cls , iterable : Iterable [tuple [str , Injectable [Any ]]]) -> Self :
861+ lazy_mapping = Lazy (lambda : dict (iterable ))
862+ return cls (lazy_mapping )
866863
867864 @classmethod
868865 def empty (cls ) -> Self :
869- return cls .from_mapping ({} )
866+ return cls .from_iterable (() )
870867
871868 @classmethod
872869 def resolve (
@@ -875,8 +872,8 @@ def resolve(
875872 module : Module ,
876873 owner : type | None = None ,
877874 ) -> Self :
878- dependencies = LazyMapping ( cls .__resolver (signature , module , owner ) )
879- return cls .from_mapping ( dependencies )
875+ iterable = cls .__resolver (signature , module , owner )
876+ return cls .from_iterable ( iterable )
880877
881878 @classmethod
882879 def __resolver (
@@ -917,21 +914,21 @@ class InjectMetadata[**P, T](Caller[P, T], EventListener):
917914 __slots__ = (
918915 "__dependencies" ,
919916 "__owner" ,
920- "__setup_queue" ,
921917 "__signature" ,
918+ "__tasks" ,
922919 "__wrapped" ,
923920 )
924921
925922 __dependencies : Dependencies
926923 __owner : type | None
927- __setup_queue : Queue [Callable [..., Any ]] | None
928924 __signature : Signature
925+ __tasks : deque [Callable [..., Any ]]
929926 __wrapped : Callable [P , T ]
930927
931928 def __init__ (self , wrapped : Callable [P , T ], / ) -> None :
932929 self .__dependencies = Dependencies .empty ()
933930 self .__owner = None
934- self .__setup_queue = Queue ()
931+ self .__tasks = deque ()
935932 self .__wrapped = wrapped
936933
937934 @property
@@ -964,12 +961,12 @@ def bind(
964961 return self .__bind (args , kwargs , additional_arguments )
965962
966963 async def acall (self , / , * args : P .args , ** kwargs : P .kwargs ) -> T :
967- self .__setup ()
964+ self .__run_tasks ()
968965 arguments = await self .abind (args , kwargs )
969966 return self .wrapped (* arguments .args , ** arguments .kwargs )
970967
971968 def call (self , / , * args : P .args , ** kwargs : P .kwargs ) -> T :
972- self .__setup ()
969+ self .__run_tasks ()
973970 arguments = self .bind (args , kwargs )
974971 return self .wrapped (* arguments .args , ** arguments .kwargs )
975972
@@ -989,14 +986,9 @@ def update(self, module: Module) -> Self:
989986 self .__dependencies = Dependencies .resolve (self .signature , module , self .__owner )
990987 return self
991988
992- def on_setup [** _P , _T ](self , wrapped : Callable [_P , _T ] | None = None , / ) -> Any :
989+ def task [** _P , _T ](self , wrapped : Callable [_P , _T ] | None = None , / ) -> Any :
993990 def decorator (wp : Callable [_P , _T ]) -> Callable [_P , _T ]:
994- queue = self .__setup_queue
995-
996- if queue is None :
997- raise RuntimeError (f"`{ self } ` is already up." )
998-
999- queue .put_nowait (wp )
991+ self .__tasks .append (wp )
1000992 return wp
1001993
1002994 return decorator (wrapped ) if wrapped else decorator
@@ -1027,24 +1019,10 @@ def __bind(
10271019 bound .arguments = bound .arguments | additional_arguments | bound .arguments
10281020 return Arguments (bound .args , bound .kwargs )
10291021
1030- def __close_setup_queue (self ) -> None :
1031- self .__setup_queue = None
1032-
1033- def __setup (self ) -> None :
1034- if (queue := self .__setup_queue ) is None :
1035- return
1036-
1037- while True :
1038- try :
1039- task = queue .get_nowait ()
1040- except Empty :
1041- break
1042-
1022+ def __run_tasks (self ) -> None :
1023+ while tasks := self .__tasks :
1024+ task = tasks .popleft ()
10431025 task ()
1044- queue .task_done ()
1045-
1046- queue .join ()
1047- self .__close_setup_queue ()
10481026
10491027
10501028class InjectedFunction [** P , T ](ABC ):
0 commit comments