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."""
@@ -280,15 +291,7 @@ async def trigger_init(self):
280
291
"event_trigger" ,
281
292
"mqtt_trigger" ,
282
293
}
283
- trig_decorators = {
284
- "time_trigger" ,
285
- "state_trigger" ,
286
- "event_trigger" ,
287
- "mqtt_trigger" ,
288
- "state_active" ,
289
- "time_active" ,
290
- "task_unique" ,
291
- }
294
+
292
295
decorator_used = set ()
293
296
for dec in self .decorators :
294
297
dec_name , dec_args , dec_kwargs = dec [0 ], dec [1 ], dec [2 ]
@@ -303,7 +306,7 @@ async def trigger_init(self):
303
306
decorator_used .add (dec_name )
304
307
if dec_name in trig_decorators_reqd :
305
308
got_reqd_dec = True
306
- if dec_name in trig_decorators :
309
+ if dec_name in TRIG_DECORATORS :
307
310
if dec_name not in trig_args :
308
311
trig_args [dec_name ] = {}
309
312
trig_args [dec_name ]["args" ] = []
@@ -383,7 +386,7 @@ async def do_service_call(func, ast_ctx, data):
383
386
dec_name ,
384
387
)
385
388
386
- for dec_name in trig_decorators :
389
+ for dec_name in TRIG_DECORATORS :
387
390
if dec_name in trig_args and len (trig_args [dec_name ]["args" ]) == 0 :
388
391
trig_args [dec_name ]["args" ] = None
389
392
@@ -518,21 +521,23 @@ async def eval_decorators(self, ast_ctx):
518
521
self .decorators = []
519
522
code_str , code_list = ast_ctx .code_str , ast_ctx .code_list
520
523
ast_ctx .code_str , ast_ctx .code_list = self .code_str , self .code_list
524
+
525
+ dec_funcs = []
521
526
for dec in self .func_def .decorator_list :
522
- if isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Name ):
523
- args = []
524
- kwargs = {}
525
- for arg in dec .args :
526
- args .append (await ast_ctx .aeval (arg ))
527
- for keyw in dec .keywords :
528
- kwargs [keyw .arg ] = await ast_ctx .aeval (keyw .value )
527
+ if isinstance (dec , ast .Call ) and isinstance (dec .func , ast .Name ) and dec .func .id in ALL_DECORATORS :
528
+ args = [await ast_ctx .aeval (arg ) for arg in dec .args ]
529
+ kwargs = {keyw .arg : await ast_ctx .aeval (keyw .value ) for keyw in dec .keywords }
529
530
if len (kwargs ) == 0 :
530
531
kwargs = None
531
532
self .decorators .append ([dec .func .id , args , kwargs ])
532
- elif isinstance (dec , ast .Name ):
533
+ elif isinstance (dec , ast .Name ) and dec . id in ALL_DECORATORS :
533
534
self .decorators .append ([dec .id , None , None ])
534
535
else :
535
- _LOGGER .error ("function %s has unexpected decorator type %s" , self .name , dec )
536
+ dec_funcs .append (await ast_ctx .aeval (dec ))
537
+
538
+ for func in reversed (dec_funcs ):
539
+ self .call = await ast_ctx .call_func (func , None , self .call )
540
+
536
541
ast_ctx .code_str , ast_ctx .code_list = code_str , code_list
537
542
538
543
async def resolve_nonlocals (self , ast_ctx ):
0 commit comments