@@ -85,7 +85,11 @@ def init(cls, hass):
85
85
"service.call" : cls .service_call ,
86
86
"service.has_service" : cls .service_has_service ,
87
87
"task.executor" : cls .task_executor ,
88
+ "task.cancel" : cls .user_task_cancel ,
89
+ "task.current_task" : cls .user_task_current_task ,
90
+ "task.remove_done_callback" : cls .user_task_remove_done_callback ,
88
91
"task.sleep" : cls .async_sleep ,
92
+ "task.wait" : cls .user_task_wait ,
89
93
}
90
94
)
91
95
cls .ast_functions .update (
@@ -95,6 +99,7 @@ def init(cls, hass):
95
99
"log.info" : lambda ast_ctx : ast_ctx .get_logger ().info ,
96
100
"log.warning" : lambda ast_ctx : ast_ctx .get_logger ().warning ,
97
101
"print" : lambda ast_ctx : ast_ctx .get_logger ().debug ,
102
+ "task.name2id" : cls .task_name2id_factory ,
98
103
"task.unique" : cls .task_unique_factory ,
99
104
}
100
105
)
@@ -124,7 +129,7 @@ async def task_reaper(reaper_q):
124
129
125
130
if not cls .task_reaper :
126
131
cls .task_reaper_q = asyncio .Queue (0 )
127
- cls .task_reaper = Function .create_task (task_reaper (cls .task_reaper_q ))
132
+ cls .task_reaper = cls .create_task (task_reaper (cls .task_reaper_q ))
128
133
129
134
#
130
135
# start a task which creates tasks to run coros, and then syncs on their completion;
@@ -153,7 +158,7 @@ async def task_waiter(waiter_q):
153
158
154
159
if not cls .task_waiter :
155
160
cls .task_waiter_q = asyncio .Queue (0 )
156
- cls .task_waiter = Function .create_task (task_waiter (cls .task_waiter_q ))
161
+ cls .task_waiter = cls .create_task (task_waiter (cls .task_waiter_q ))
157
162
158
163
@classmethod
159
164
def reaper_cancel (cls , task ):
@@ -230,12 +235,12 @@ async def task_unique(name, kill_me=False):
230
235
# it seems we can't cancel ourselves, so we
231
236
# tell the reaper task to cancel us
232
237
#
233
- Function .reaper_cancel (curr_task )
238
+ cls .reaper_cancel (curr_task )
234
239
# wait to be canceled
235
240
await asyncio .sleep (100000 )
236
241
elif task != curr_task and task in cls .our_tasks :
237
242
# only cancel tasks if they are ones we started
238
- Function .reaper_cancel (task )
243
+ cls .reaper_cancel (task )
239
244
if curr_task in cls .our_tasks :
240
245
if name in cls .unique_name2task :
241
246
task = cls .unique_name2task [name ]
@@ -255,6 +260,45 @@ async def task_executor(cls, func, *args, **kwargs):
255
260
raise TypeError ("function is not callable by task.executor()" )
256
261
return await cls .hass .async_add_executor_job (functools .partial (func , ** kwargs ), * args )
257
262
263
+ @classmethod
264
+ def user_task_cancel (cls , task ):
265
+ """Implement task.cancel()."""
266
+ if not isinstance (task , asyncio .Task ):
267
+ raise TypeError (f"{ task } is not of type asyncio.Task" )
268
+ cls .reaper_cancel (task )
269
+
270
+ @classmethod
271
+ async def user_task_current_task (cls ):
272
+ """Implement task.current_task()."""
273
+ return asyncio .current_task ()
274
+
275
+ @classmethod
276
+ def task_name2id_factory (cls , ctx ):
277
+ """Define and return task.name2id() for this context."""
278
+
279
+ def user_task_name2id (name = None ):
280
+ """Implement task.name2id()."""
281
+ prefix = f"{ ctx .get_global_ctx_name ()} ."
282
+ if name is None :
283
+ ret = {}
284
+ for task_name , task_id in cls .unique_name2task .items ():
285
+ if task_name .startswith (prefix ):
286
+ ret [task_name [len (prefix ) :]] = task_id
287
+ return ret
288
+ return cls .unique_name2task .get (prefix + name , None )
289
+
290
+ return user_task_name2id
291
+
292
+ @classmethod
293
+ async def user_task_wait (cls , aws ):
294
+ """Implement task.wait()."""
295
+ return await asyncio .wait (aws )
296
+
297
+ @classmethod
298
+ def user_task_remove_done_callback (cls , task , callback ):
299
+ """Implement task.remove_done_callback()."""
300
+ cls .task2cb [task ]["cb" ].pop (callback , None )
301
+
258
302
@classmethod
259
303
def unique_name_used (cls , ctx , name ):
260
304
"""Return whether the current unique name is in use."""
@@ -423,8 +467,3 @@ def task_add_done_callback(cls, task, ast_ctx, callback, *args, **kwargs):
423
467
if ast_ctx is None :
424
468
ast_ctx = cls .task2cb [task ]["ctx" ]
425
469
cls .task2cb [task ]["cb" ][callback ] = [ast_ctx , args , kwargs ]
426
-
427
- @classmethod
428
- def task_remove_done_callback (cls , task , callback ):
429
- """Remove a done callback to the given task."""
430
- cls .task2cb [task ]["cb" ].pop (callback , None )
0 commit comments