Skip to content

Commit f97d965

Browse files
committed
feat: add Task methods: exception, result, get_coro, and cancelled
1 parent d22adcf commit f97d965

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed

extmod/modasyncio.c

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ typedef struct _mp_obj_task_queue_t {
5959
mp_obj_task_t *heap;
6060
} mp_obj_task_queue_t;
6161

62+
MP_DEFINE_EXCEPTION(CancelledError, BaseException)
63+
MP_DEFINE_EXCEPTION(InvalidStateError, Exception)
64+
6265
STATIC const mp_obj_type_t task_queue_type;
6366
STATIC const mp_obj_type_t task_type;
6467

@@ -194,6 +197,85 @@ STATIC mp_obj_t task_get_coro(mp_obj_t self_in) {
194197
}
195198
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_get_coro_obj, task_get_coro);
196199

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+
197279
STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
198280
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
199281
// 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) {
271353
} else if (attr == MP_QSTR_get_coro) {
272354
dest[0] = MP_OBJ_FROM_PTR(&task_get_coro_obj);
273355
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;
274371
}
275372
} else if (dest[1] != MP_OBJ_NULL) {
276373
// Store
@@ -285,9 +382,9 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
285382
}
286383

287384
STATIC mp_obj_t task_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
288-
switch(op) {
385+
switch (op) {
289386
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);
291388
default:
292389
return MP_OBJ_NULL; // op not supported
293390
}
@@ -352,6 +449,8 @@ STATIC const mp_rom_map_elem_t mp_module_asyncio_globals_table[] = {
352449
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__asyncio) },
353450
{ MP_ROM_QSTR(MP_QSTR_TaskQueue), MP_ROM_PTR(&task_queue_type) },
354451
{ 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) },
355454
};
356455
STATIC MP_DEFINE_CONST_DICT(mp_module_asyncio_globals, mp_module_asyncio_globals_table);
357456

locale/circuitpython.pot

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,10 @@ msgstr ""
988988
msgid "Error: Failure to bind"
989989
msgstr ""
990990

991+
#: extmod/modasyncio.c
992+
msgid "Exception is not set."
993+
msgstr ""
994+
991995
#: shared-bindings/alarm/__init__.c
992996
msgid "Expected a kind of %q"
993997
msgstr ""
@@ -1887,6 +1891,10 @@ msgstr ""
18871891
msgid "Requested resource not found"
18881892
msgstr ""
18891893

1894+
#: extmod/modasyncio.c
1895+
msgid "Result is not ready."
1896+
msgstr ""
1897+
18901898
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
18911899
msgid "Right channel unsupported"
18921900
msgstr ""
@@ -1992,6 +2000,14 @@ msgstr ""
19922000
msgid "System entry must be gnss.SatelliteSystem"
19932001
msgstr ""
19942002

2003+
#: extmod/modasyncio.c
2004+
msgid "Task does not support set_exception operation"
2005+
msgstr ""
2006+
2007+
#: extmod/modasyncio.c
2008+
msgid "Task does not support set_result operation"
2009+
msgstr ""
2010+
19952011
#: ports/stm/common-hal/microcontroller/Processor.c
19962012
msgid "Temperature read timed out"
19972013
msgstr ""

0 commit comments

Comments
 (0)