46
46
_thread_lock = RLock ()
47
47
48
48
_T = TypeVar ("_T" )
49
+ Types = Iterable [type ] | UnionType
49
50
50
51
51
52
"""
@@ -211,7 +212,7 @@ def is_locked(self) -> bool:
211
212
def __injectables (self ) -> frozenset [Injectable ]:
212
213
return frozenset (self .__data .values ())
213
214
214
- def update (self , classes : Iterable [ type ] | UnionType , injectable : Injectable ):
215
+ def update (self , classes : Types , injectable : Injectable ):
215
216
classes = frozenset (get_origins (* classes ))
216
217
217
218
if classes :
@@ -308,7 +309,16 @@ def __brokers(self) -> Iterator[Container | Module]:
308
309
yield from tuple (self .__modules )
309
310
yield self .__container
310
311
311
- def get_instance (self , cls : type [_T ] | UnionType ) -> _T | None :
312
+ def constant (self , instance : _T , on : type | Types = None ) -> _T :
313
+ cls = type (instance )
314
+
315
+ @self .injectable (on = (cls , on ))
316
+ def get_constant ():
317
+ return instance
318
+
319
+ return instance
320
+
321
+ def get_instance (self , cls : type [_T ]) -> _T | None :
312
322
try :
313
323
injectable = self [cls ]
314
324
except KeyError :
@@ -317,10 +327,10 @@ def get_instance(self, cls: type[_T] | UnionType) -> _T | None:
317
327
instance = injectable .get_instance ()
318
328
return cast (cls , instance )
319
329
320
- def get_lazy_instance (self , cls : type [_T ] | UnionType ) -> Lazy [_T | None ]:
330
+ def get_lazy_instance (self , cls : type [_T ]) -> Lazy [_T | None ]:
321
331
return Lazy (lambda : self .get_instance (cls ))
322
332
323
- def update (self , classes : Iterable [ type ] | UnionType , injectable : Injectable ):
333
+ def update (self , classes : Types , injectable : Injectable ):
324
334
self .__container .update (classes , injectable )
325
335
return self
326
336
@@ -548,39 +558,29 @@ def __call__(
548
558
wrapped : Callable [..., Any ] = None ,
549
559
/ ,
550
560
* ,
551
- on : type | Iterable [ type ] | UnionType = None ,
561
+ on : type | Types = None ,
552
562
):
553
563
def decorator (wp ):
554
- @lambda fn : fn ()
555
- def classes ():
556
- if cls := self .__get_class (wp ):
557
- yield cls
558
-
559
- if on is None :
560
- return
561
- elif isinstance (on , type | str ):
562
- yield on
563
- else :
564
- yield from on
565
-
566
564
@self .__module .inject
567
565
@wraps (wp , updated = ())
568
566
def factory (* args , ** kwargs ):
569
567
return wp (* args , ** kwargs )
570
568
571
569
injectable = self .__injectable_type (factory )
570
+ classes = self .__get_classes (wp , on )
572
571
self .__module .update (classes , injectable )
573
-
574
572
return wp
575
573
576
574
return decorator (wrapped ) if wrapped else decorator
577
575
578
- @staticmethod
579
- def __get_class (wrapped : Callable [..., Any ]) -> type | None :
580
- if isclass (wrapped ):
581
- return wrapped
576
+ @classmethod
577
+ def __get_classes (cls , * objects : Any ) -> Iterator [type | UnionType ]:
578
+ for obj in objects :
579
+ if isinstance (obj , Iterable ) and not isinstance (obj , type | str ):
580
+ yield from cls .__get_classes (* obj )
582
581
583
- if isfunction (wrapped ):
584
- return get_annotations (wrapped , eval_str = True ).get ("return" )
582
+ elif isfunction (obj ):
583
+ yield get_annotations (obj , eval_str = True ).get ("return" )
585
584
586
- return None
585
+ else :
586
+ yield obj
0 commit comments