41
41
"print" ,
42
42
}
43
43
44
+ TRIG_DECORATORS = {
45
+ "time_trigger" ,
46
+ "state_trigger" ,
47
+ "event_trigger" ,
48
+ "mqtt_trigger" ,
49
+ "state_active" ,
50
+ "time_active" ,
51
+ "task_unique" ,
52
+ }
53
+
54
+ ALL_DECORATORS = TRIG_DECORATORS .union ({"service" })
44
55
45
56
def ast_eval_exec_factory (ast_ctx , mode ):
46
57
"""Generate a function that executes eval() or exec() with given ast_ctx."""
@@ -255,7 +266,6 @@ def __init__(self, func_def, code_list, code_str, global_ctx):
255
266
self .trigger = None
256
267
self .trigger_service = False
257
268
self .has_closure = False
258
- self .perform_call = None
259
269
260
270
def get_name (self ):
261
271
"""Return the function name."""
@@ -281,15 +291,6 @@ async def trigger_init(self):
281
291
"event_trigger" ,
282
292
"mqtt_trigger" ,
283
293
}
284
- trig_decorators = {
285
- "time_trigger" ,
286
- "state_trigger" ,
287
- "event_trigger" ,
288
- "mqtt_trigger" ,
289
- "state_active" ,
290
- "time_active" ,
291
- "task_unique" ,
292
- }
293
294
decorator_used = set ()
294
295
for dec in self .decorators :
295
296
dec_name , dec_args , dec_kwargs = dec [0 ], dec [1 ], dec [2 ]
@@ -304,7 +305,7 @@ async def trigger_init(self):
304
305
decorator_used .add (dec_name )
305
306
if dec_name in trig_decorators_reqd :
306
307
got_reqd_dec = True
307
- if dec_name in trig_decorators :
308
+ if dec_name in TRIG_DECORATORS :
308
309
if dec_name not in trig_args :
309
310
trig_args [dec_name ] = {}
310
311
trig_args [dec_name ]["args" ] = []
@@ -384,7 +385,7 @@ async def do_service_call(func, ast_ctx, data):
384
385
dec_name ,
385
386
)
386
387
387
- for dec_name in trig_decorators :
388
+ for dec_name in TRIG_DECORATORS :
388
389
if dec_name in trig_args and len (trig_args [dec_name ]["args" ]) == 0 :
389
390
trig_args [dec_name ]["args" ] = None
390
391
@@ -520,85 +521,21 @@ async def eval_decorators(self, ast_ctx):
520
521
code_str , code_list = ast_ctx .code_str , ast_ctx .code_list
521
522
ast_ctx .code_str , ast_ctx .code_list = self .code_str , self .code_list
522
523
523
- decorator_chain_funcs = []
524
-
524
+ dec_funcs = []
525
525
for dec in self .func_def .decorator_list :
526
- # this should eventually handle:
527
- # SomeClass('a','b').some_method('x','y')
528
- if isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Attribute ):
529
- _LOGGER .info (
530
- "Attribute as decorator (ignoring for now) %s %s %s" ,
531
- dec .func ,
532
- dec .func .attr ,
533
- dec .func .value
534
- )
535
-
536
- elif isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Name ):
537
- args = []
538
- kwargs = {}
539
- for arg in dec .args :
540
- args .append (await ast_ctx .aeval (arg ))
541
- for keyw in dec .keywords :
542
- kwargs [keyw .arg ] = await ast_ctx .aeval (keyw .value )
526
+ if isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Name ) and dec .func .id in ALL_DECORATORS :
527
+ args = [await ast_ctx .aeval (arg ) for arg in dec .args ]
528
+ kwargs = {keyw .arg : await ast_ctx .aeval (keyw .value ) for keyw in dec .keywords }
543
529
if len (kwargs ) == 0 :
544
530
kwargs = None
545
-
546
- if dec .func .id in ast_ctx .global_sym_table :
547
- _LOGGER .info (
548
- "added %s to decorator_chain_funcs" ,
549
- dec .func .id ,
550
- )
551
- decorator_chain_funcs .append (dec )
552
- else :
553
- self .decorators .append ([dec .func .id , args , kwargs ])
554
- elif isinstance (dec , ast .Name ):
555
- if dec .id in ast_ctx .global_sym_table :
556
- decorator_chain_funcs .append (dec )
557
- else :
558
- self .decorators .append ([dec .id , None , None ])
531
+ self .decorators .append ([dec .func .id , args , kwargs ])
532
+ elif isinstance (dec , ast .Name ) and dec .id in ALL_DECORATORS :
533
+ self .decorators .append ([dec .id , None , None ])
559
534
else :
560
- _LOGGER .error ("function %s has unexpected decorator type %s" , self .name , dec )
561
-
562
- actual_call = self .real_call
563
-
564
- try :
565
- for dec in reversed (decorator_chain_funcs ):
566
- if isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Name ):
567
- args = []
568
- kwargs = {}
569
- for arg in dec .args :
570
- args .append (await ast_ctx .aeval (arg ))
571
- for keyw in dec .keywords :
572
- kwargs [keyw .arg ] = await ast_ctx .aeval (keyw .value )
573
- if len (kwargs ) == 0 :
574
- kwargs = {}
575
- func_def = ast_ctx .global_sym_table [dec .func .id ]
576
-
577
- wrapper = await func_def .call (ast_ctx , * args , ** kwargs )
578
- def make_actual_call_inner (actual_call ):
579
- async def actual_call_inner (* args_tuple , ** kwargs ):
580
- args = list (args_tuple )
581
- if len (args ) > 0 and isinstance (args [0 ], AstEval ):
582
- _LOGGER .info ('AstEval seen' )
583
- args .pop (0 )
584
- _LOGGER .info (actual_call )
585
- return await actual_call (ast_ctx , * args , ** kwargs )
586
- return actual_call_inner
587
- actual_call = await wrapper (make_actual_call_inner (actual_call ))
588
-
589
- elif isinstance (dec , ast .Name ):
590
- func_def = ast_ctx .global_sym_table [dec .id ]
591
- actual_call = await func_def .call (ast_ctx , actual_call )
535
+ dec_funcs .append (await ast_ctx .aeval (dec ))
592
536
593
- else :
594
- _LOGGER .error ("function %s has unexpected global_sym_table decorator type %s" , self .name , dec )
595
- except Exception as e :
596
- _LOGGER .error (
597
- "Something went wrong %s" ,
598
- e
599
- )
600
-
601
- self .perform_call = actual_call
537
+ for func in reversed (dec_funcs ):
538
+ self .call = await ast_ctx .call_func (func , None , self .call )
602
539
603
540
ast_ctx .code_str , ast_ctx .code_list = code_str , code_list
604
541
@@ -680,13 +617,9 @@ async def try_aeval(self, ast_ctx, arg):
680
617
ast_ctx .exception_long = ast_ctx .format_exc (err , arg .lineno , arg .col_offset )
681
618
682
619
async def call (self , ast_ctx , * args , ** kwargs ):
683
- """Call the function with decorators"""
684
- return await self .perform_call (ast_ctx , * args , ** kwargs )
685
-
686
- async def real_call (self , ast_ctx , * args , ** kwargs ):
687
620
"""Call the function with the given context and arguments."""
688
621
_LOGGER .info (
689
- 'in real_call of %s' ,
622
+ 'in call of %s' ,
690
623
self .name
691
624
)
692
625
sym_table = {}
0 commit comments