@@ -59,6 +59,9 @@ typedef struct _mp_obj_task_queue_t {
59
59
mp_obj_task_t * heap ;
60
60
} mp_obj_task_queue_t ;
61
61
62
+ MP_DEFINE_EXCEPTION (CancelledError , BaseException )
63
+ MP_DEFINE_EXCEPTION (InvalidStateError , Exception )
64
+
62
65
STATIC const mp_obj_type_t task_queue_type ;
63
66
STATIC const mp_obj_type_t task_type ;
64
67
@@ -194,6 +197,85 @@ STATIC mp_obj_t task_get_coro(mp_obj_t self_in) {
194
197
}
195
198
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (task_get_coro_obj , task_get_coro );
196
199
200
+ STATIC mp_obj_t task_set_exception (mp_obj_t self_in , const mp_obj_t arg ) {
201
+ mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("Task does not support set_exception operation" ));
202
+ }
203
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (task_set_exception_obj , task_set_exception );
204
+
205
+ STATIC mp_obj_t task_exception (mp_obj_t self_in ) {
206
+ mp_obj_task_t * self = MP_OBJ_TO_PTR (self_in );
207
+
208
+ if (!TASK_IS_DONE (self )) {
209
+ mp_raise_msg (& mp_type_InvalidStateError , MP_ERROR_TEXT ("Exception is not set." ));
210
+ return NULL ;
211
+ }
212
+
213
+ mp_obj_t data_obj = self -> data ;
214
+
215
+ // If the exception is a cancelled error then we should raise it
216
+ if (mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (mp_obj_get_type (data_obj )), MP_OBJ_FROM_PTR (& mp_type_CancelledError ))) {
217
+ nlr_raise (data_obj );
218
+ }
219
+
220
+ // If it's a StopIteration we should should return none
221
+ if (mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (mp_obj_get_type (data_obj )), MP_OBJ_FROM_PTR (& mp_type_StopIteration ))) {
222
+ return mp_const_none ;
223
+ }
224
+
225
+ if (!mp_obj_is_exception_instance (data_obj )) {
226
+ return mp_const_none ;
227
+ }
228
+
229
+ return data_obj ;
230
+ }
231
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (task_exception_obj , task_exception );
232
+
233
+ STATIC mp_obj_t task_set_result (mp_obj_t self_in , const mp_obj_t arg ) {
234
+ mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("Task does not support set_result operation" ));
235
+ }
236
+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (task_set_result_obj , task_set_result );
237
+
238
+ STATIC mp_obj_t task_result (mp_obj_t self_in ) {
239
+ mp_obj_task_t * self = MP_OBJ_TO_PTR (self_in );
240
+
241
+ if (!TASK_IS_DONE (self )) {
242
+ mp_raise_msg (& mp_type_InvalidStateError , MP_ERROR_TEXT ("Result is not ready." ));
243
+ return NULL ;
244
+ }
245
+
246
+ // If `exception()` returns anything we raise that
247
+ mp_obj_t exception_obj = task_exception (self_in );
248
+ if (exception_obj != mp_const_none ) {
249
+ nlr_raise (exception_obj );
250
+ }
251
+
252
+ mp_obj_t data_obj = self -> data ;
253
+
254
+ // If not StopIteration, bail early
255
+ if (!mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (mp_obj_get_type (data_obj )), MP_OBJ_FROM_PTR (& mp_type_StopIteration ))) {
256
+ return mp_const_none ;
257
+ }
258
+
259
+ return mp_obj_exception_get_value (data_obj );
260
+ }
261
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (task_result_obj , task_result );
262
+
263
+ STATIC mp_obj_t task_cancelled (mp_obj_t self_in ) {
264
+ mp_obj_task_t * self = MP_OBJ_TO_PTR (self_in );
265
+
266
+ if (!TASK_IS_DONE (self )) {
267
+ // If task isn't done it can't possibly be cancelled, and would instead
268
+ // be considered "cancelling" even if a cancel was requested until it
269
+ // has fully completed.
270
+ return mp_obj_new_bool (false);
271
+ }
272
+
273
+ mp_obj_t data_obj = self -> data ;
274
+
275
+ return mp_obj_new_bool (mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (mp_obj_get_type (data_obj )), MP_OBJ_FROM_PTR (& mp_type_CancelledError )));
276
+ }
277
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (task_cancelled_obj , task_cancelled );
278
+
197
279
STATIC mp_obj_t task_cancel (mp_obj_t self_in ) {
198
280
mp_obj_task_t * self = MP_OBJ_TO_PTR (self_in );
199
281
// Check if task is already finished.
@@ -271,6 +353,21 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
271
353
} else if (attr == MP_QSTR_get_coro ) {
272
354
dest [0 ] = MP_OBJ_FROM_PTR (& task_get_coro_obj );
273
355
dest [1 ] = self_in ;
356
+ } else if (attr == MP_QSTR_set_result ) {
357
+ dest [0 ] = MP_OBJ_FROM_PTR (& task_set_result_obj );
358
+ dest [1 ] = self_in ;
359
+ } else if (attr == MP_QSTR_result ) {
360
+ dest [0 ] = MP_OBJ_FROM_PTR (& task_result_obj );
361
+ dest [1 ] = self_in ;
362
+ } else if (attr == MP_QSTR_set_exception ) {
363
+ dest [0 ] = MP_OBJ_FROM_PTR (& task_set_exception_obj );
364
+ dest [1 ] = self_in ;
365
+ } else if (attr == MP_QSTR_exception ) {
366
+ dest [0 ] = MP_OBJ_FROM_PTR (& task_exception_obj );
367
+ dest [1 ] = self_in ;
368
+ } else if (attr == MP_QSTR_cancelled ) {
369
+ dest [0 ] = MP_OBJ_FROM_PTR (& task_cancelled_obj );
370
+ dest [1 ] = self_in ;
274
371
}
275
372
} else if (dest [1 ] != MP_OBJ_NULL ) {
276
373
// Store
@@ -285,9 +382,9 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
285
382
}
286
383
287
384
STATIC mp_obj_t task_unary_op (mp_unary_op_t op , mp_obj_t o_in ) {
288
- switch (op ) {
385
+ switch (op ) {
289
386
case MP_UNARY_OP_HASH :
290
- return MP_OBJ_NEW_SMALL_INT ((mp_uint_t ) o_in );
387
+ return MP_OBJ_NEW_SMALL_INT ((mp_uint_t )o_in );
291
388
default :
292
389
return MP_OBJ_NULL ; // op not supported
293
390
}
@@ -352,6 +449,8 @@ STATIC const mp_rom_map_elem_t mp_module_asyncio_globals_table[] = {
352
449
{ MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR__asyncio ) },
353
450
{ MP_ROM_QSTR (MP_QSTR_TaskQueue ), MP_ROM_PTR (& task_queue_type ) },
354
451
{ MP_ROM_QSTR (MP_QSTR_Task ), MP_ROM_PTR (& task_type ) },
452
+ { MP_ROM_QSTR (MP_QSTR_CancelledError ), MP_ROM_PTR (& mp_type_CancelledError ) },
453
+ { MP_ROM_QSTR (MP_QSTR_InvalidStateError ), MP_ROM_PTR (& mp_type_InvalidStateError ) },
355
454
};
356
455
STATIC MP_DEFINE_CONST_DICT (mp_module_asyncio_globals , mp_module_asyncio_globals_table );
357
456
0 commit comments