38
38
39
39
from injection .common .event import Event , EventChannel , EventListener
40
40
from injection .common .lazy import Lazy , LazyMapping
41
+ from injection .common .queue import LimitedQueue
41
42
from injection .common .tools .threading import (
42
43
frozen_collection ,
43
44
synchronized ,
@@ -418,9 +419,14 @@ def decorator(wp):
418
419
wp .__init__ = self .inject (wp .__init__ )
419
420
return wp
420
421
421
- wrapper = InjectedFunction (wp ).update (self )
422
- self .add_listener (wrapper )
423
- return wrapper
422
+ function = InjectedFunction (wp )
423
+
424
+ @function .setup
425
+ def listen ():
426
+ function .update (self )
427
+ self .add_listener (function )
428
+
429
+ return function
424
430
425
431
return decorator (wrapped ) if wrapped else decorator
426
432
@@ -612,22 +618,36 @@ class Arguments(NamedTuple):
612
618
613
619
614
620
class InjectedFunction (EventListener ):
615
- __slots__ = ("__dict__" , "__wrapper" , "__dependencies" , "__owner" )
621
+ __slots__ = (
622
+ "__dict__" ,
623
+ "__signature__" ,
624
+ "__dependencies" ,
625
+ "__owner" ,
626
+ "__setup_queue" ,
627
+ "__wrapper" ,
628
+ )
616
629
617
630
def __init__ (self , wrapped : Callable [..., Any ], / ):
618
631
update_wrapper (self , wrapped )
619
- self .__signature__ = Lazy [Signature ](
620
- lambda : inspect .signature (wrapped , eval_str = True )
621
- )
622
632
623
633
@wraps (wrapped )
624
634
def wrapper (* args , ** kwargs ):
635
+ self .__consume_setup_queue ()
625
636
args , kwargs = self .bind (args , kwargs )
626
637
return wrapped (* args , ** kwargs )
627
638
628
639
self .__wrapper = wrapper
629
640
self .__dependencies = Dependencies .empty ()
630
641
self .__owner = None
642
+ self .__setup_queue = LimitedQueue [Callable [[], Any ]]()
643
+ self .setup (
644
+ lambda : self .__set_signature (
645
+ inspect .signature (
646
+ wrapped ,
647
+ eval_str = True ,
648
+ )
649
+ )
650
+ )
631
651
632
652
def __repr__ (self ) -> str :
633
653
return repr (self .__wrapper )
@@ -638,7 +658,7 @@ def __str__(self) -> str:
638
658
def __call__ (self , / , * args , ** kwargs ) -> Any :
639
659
return self .__wrapper (* args , ** kwargs )
640
660
641
- def __get__ (self , instance : object | None , owner : type ):
661
+ def __get__ (self , instance : object = None , owner : type = None ):
642
662
if instance is None :
643
663
return self
644
664
@@ -647,7 +667,7 @@ def __get__(self, instance: object | None, owner: type):
647
667
def __set_name__ (self , owner : type , name : str ):
648
668
if self .__dependencies .are_resolved :
649
669
raise TypeError (
650
- "`__set_name__` is called after dependencies have been resolved."
670
+ "Function owner must be assigned before dependencies are resolved."
651
671
)
652
672
653
673
if self .__owner :
@@ -657,7 +677,7 @@ def __set_name__(self, owner: type, name: str):
657
677
658
678
@property
659
679
def signature (self ) -> Signature :
660
- return self .__signature__ ()
680
+ return self .__signature__
661
681
662
682
def bind (
663
683
self ,
@@ -671,9 +691,9 @@ def bind(
671
691
return Arguments (args , kwargs )
672
692
673
693
bound = self .signature .bind_partial (* args , ** kwargs )
674
- dependencies = self . __dependencies . arguments
675
- bound .arguments = dependencies | bound .arguments
676
-
694
+ bound . arguments = (
695
+ bound .arguments | self . __dependencies . arguments | bound .arguments
696
+ )
677
697
return Arguments (bound .args , bound .kwargs )
678
698
679
699
def update (self , module : Module ):
@@ -686,6 +706,13 @@ def update(self, module: Module):
686
706
687
707
return self
688
708
709
+ def setup (self , wrapped : Callable [[], Any ] = None , / ):
710
+ def decorator (wp ):
711
+ self .__setup_queue .add (wp )
712
+ return wp
713
+
714
+ return decorator (wrapped ) if wrapped else decorator
715
+
689
716
@singledispatchmethod
690
717
def on_event (self , event : Event , / ):
691
718
pass
@@ -695,3 +722,15 @@ def on_event(self, event: Event, /):
695
722
def _ (self , event : ModuleEvent , / ) -> ContextManager :
696
723
yield
697
724
self .update (event .on_module )
725
+
726
+ def __consume_setup_queue (self ):
727
+ for function in self .__setup_queue :
728
+ function ()
729
+
730
+ return self
731
+
732
+ def __set_signature (self , signature : Signature ):
733
+ with thread_lock :
734
+ self .__signature__ = signature
735
+
736
+ return self
0 commit comments