@@ -58,13 +58,14 @@ async def trigger_init(self, func):
5858 "event_trigger" ,
5959 "state_active" ,
6060 "time_active" ,
61+ "task_unique" ,
6162 }
6263 decorator_used = set ()
6364 for dec in func .get_decorators ():
64- dec_name , dec_args = dec [0 ], dec [1 ]
65+ dec_name , dec_args , dec_kwargs = dec [0 ], dec [1 ], dec [ 2 ]
6566 if dec_name in decorator_used :
6667 self .logger .error (
67- "%s defined in %s: decorator %s repeated; ignored " ,
68+ "%s defined in %s: decorator %s repeated; ignoring decorator " ,
6869 func_name ,
6970 self .name ,
7071 dec_name ,
@@ -75,13 +76,16 @@ async def trigger_init(self, func):
7576 got_reqd_dec = True
7677 if dec_name in trig_decorators :
7778 if dec_name not in trig_args :
78- trig_args [dec_name ] = []
79+ trig_args [dec_name ] = {}
80+ trig_args [dec_name ]["args" ] = []
7981 if dec_args is not None :
80- trig_args [dec_name ] += dec_args
82+ trig_args [dec_name ]["args" ] += dec_args
83+ if dec_kwargs is not None :
84+ trig_args [dec_name ]["kwargs" ] = dec_kwargs
8185 elif dec_name == "service" :
8286 if dec_args is not None :
8387 self .logger .error (
84- "%s defined in %s: decorator @service takes no arguments; ignored " ,
88+ "%s defined in %s: decorator @service takes no arguments; ignoring decorator " ,
8589 func_name ,
8690 self .name ,
8791 )
@@ -167,30 +171,71 @@ async def do_service_call(func, ast_ctx, data):
167171 self .services .discard (func_name )
168172
169173 for dec_name in trig_decorators :
170- if dec_name in trig_args and len (trig_args [dec_name ]) == 0 :
171- trig_args [dec_name ] = None
174+ if dec_name in trig_args and len (trig_args [dec_name ][ "args" ] ) == 0 :
175+ trig_args [dec_name ][ "args" ] = None
172176
177+ #
178+ # check that we have the right number of arguments, and that they are
179+ # strings
180+ #
173181 arg_check = {
174- "state_trigger" : {1 },
175- "state_active" : {1 },
176182 "event_trigger" : {1 , 2 },
183+ "state_active" : {1 },
184+ "state_trigger" : {1 },
185+ "task_unique" : {1 },
186+ "time_active" : {"*" },
187+ "time_trigger" : {"*" },
177188 }
178189 for dec_name , arg_cnt in arg_check .items ():
179- if dec_name not in trig_args or trig_args [dec_name ] is None :
190+ if dec_name not in trig_args or trig_args [dec_name ][ "args" ] is None :
180191 continue
181- if len (trig_args [dec_name ]) not in arg_cnt :
192+ if "*" not in arg_cnt and len (trig_args [dec_name ][ "args" ]) not in arg_cnt :
182193 self .logger .error (
183- "%s defined in %s: decorator @%s got %d argument%s, expected %s; ignored " ,
194+ "%s defined in %s: decorator @%s got %d argument%s, expected %s; ignoring decorator " ,
184195 func_name ,
185196 self .name ,
186197 dec_name ,
187- len (trig_args [dec_name ]),
188- "s" if len (trig_args [dec_name ]) > 1 else "" ,
198+ len (trig_args [dec_name ][ "args" ] ),
199+ "s" if len (trig_args [dec_name ][ "args" ] ) > 1 else "" ,
189200 " or " .join ([str (cnt ) for cnt in sorted (arg_cnt )]),
190201 )
191202 del trig_args [dec_name ]
192- if arg_cnt == 1 :
193- trig_args [dec_name ] = trig_args [dec_name ][0 ]
203+ break
204+ for arg_num , arg in enumerate (trig_args [dec_name ]["args" ]):
205+ if not isinstance (arg , str ):
206+ self .logger .error (
207+ "%s defined in %s: decorator @%s argument %d should be a string; ignoring decorator" ,
208+ func_name ,
209+ self .name ,
210+ dec_name ,
211+ arg_num + 1
212+ )
213+ del trig_args [dec_name ]
214+ break
215+ if arg_cnt == {1 }:
216+ trig_args [dec_name ]["args" ] = trig_args [dec_name ]["args" ][0 ]
217+
218+ kwarg_check = {
219+ "task_unique" : {"kill_me" },
220+ }
221+ for dec_name in trig_args .keys ():
222+ if dec_name not in kwarg_check and "kwargs" in trig_args [dec_name ]:
223+ self .logger .error (
224+ "%s defined in %s: decorator @%s doesn't take keyword arguments; ignored" ,
225+ func_name ,
226+ self .name ,
227+ dec_name ,
228+ )
229+ if dec_name in kwarg_check and "kwargs" in trig_args [dec_name ]:
230+ used_kw = set (trig_args [dec_name ]["kwargs" ].keys ())
231+ if not used_kw .issubset (kwarg_check [dec_name ]):
232+ self .logger .error (
233+ "%s defined in %s: decorator @%s valid keyword arguments are: %s; others ignored" ,
234+ func_name ,
235+ self .name ,
236+ dec_name ,
237+ ", " .join (sorted (kwarg_check [dec_name ])),
238+ )
194239
195240 if not got_reqd_dec and len (trig_args ) > 0 :
196241 self .logger .error (
0 commit comments