Skip to content

Commit c0b28c4

Browse files
committed
Merge remote-tracking branch 'origin/main' into main
2 parents 9f65ccc + a7e353b commit c0b28c4

File tree

140 files changed

+1655
-604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+1655
-604
lines changed

.git-blame-ignore-revs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
2+
0f78c36c5aa458a954eed39a46942209107a553e
3+
14
# tests/run-tests.py: Reformat with Black.
25
2a38d7103672580882fb621a5b76e8d26805d593
36

docs/library/builtins.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,6 @@ Exceptions
182182

183183
.. exception:: OSError
184184

185-
|see_cpython| :py:class:`cpython:OSError`. CircuitPython doesn't implement the ``errno``
186-
attribute, instead use the standard way to access exception arguments:
187-
``exc.args[0]``.
188-
189185
.. exception:: RuntimeError
190186

191187
.. exception:: ReloadException

docs/library/uasyncio.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,14 @@ TCP stream connections
214214

215215
This is a coroutine.
216216

217+
.. method:: Stream.readinto(buf)
218+
219+
Read up to n bytes into *buf* with n being equal to the length of *buf*.
220+
221+
Return the number of bytes read into *buf*.
222+
223+
This is a coroutine, and a MicroPython extension.
224+
217225
.. method:: Stream.readline()
218226

219227
Read a line and return it.

docs/library/uctypes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ Module contents
247247

248248
.. data:: VOID
249249

250-
``VOID`` is an alias for ``UINT8``, and is provided to conviniently define
250+
``VOID`` is an alias for ``UINT8``, and is provided to conveniently define
251251
C's void pointers: ``(uctypes.PTR, uctypes.VOID)``.
252252

253253
.. data:: PTR

docs/library/uheapq.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88

99
|see_cpython_module| :mod:`cpython:heapq`.
1010

11-
This module implements the heap queue algorithm.
11+
This module implements the
12+
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
1213

13-
A heap queue is simply a list that has its elements stored in a certain way.
14+
A heap queue is essentially a list that has its elements stored in such a way
15+
that the first item of the list is always the smallest.
1416

1517
Functions
1618
---------
@@ -21,8 +23,10 @@ Functions
2123

2224
.. function:: heappop(heap)
2325

24-
Pop the first item from the ``heap``, and return it. Raises IndexError if
25-
heap is empty.
26+
Pop the first item from the ``heap``, and return it. Raise ``IndexError`` if
27+
``heap`` is empty.
28+
29+
The returned item will be the smallest item in the ``heap``.
2630

2731
.. function:: heapify(x)
2832

docs/library/uselect.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ Methods
8989
``callee-owned tuples``. This function provides efficient, allocation-free
9090
way to poll on streams.
9191

92-
If *flags* is 1, one-shot behavior for events is employed: streams for
92+
If *flags* is 1, one-shot behaviour for events is employed: streams for
9393
which events happened will have their event masks automatically reset
9494
(equivalent to ``poll.modify(obj, 0)``), so new events for such a stream
9595
won't be processed until new mask is set with `poll.modify()`. This
96-
behavior is useful for asynchronous I/O schedulers.
96+
behaviour is useful for asynchronous I/O schedulers.
9797

9898
.. admonition:: Difference to CPython
9999
:class: attention

extmod/moduasyncio.c

Lines changed: 22 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@
3131

3232
#if MICROPY_PY_UASYNCIO
3333

34+
#define TASK_STATE_RUNNING_NOT_WAITED_ON (mp_const_true)
35+
#define TASK_STATE_DONE_NOT_WAITED_ON (mp_const_none)
36+
#define TASK_STATE_DONE_WAS_WAITED_ON (mp_const_false)
37+
38+
#define TASK_IS_DONE(task) ( \
39+
(task)->state == TASK_STATE_DONE_NOT_WAITED_ON \
40+
|| (task)->state == TASK_STATE_DONE_WAS_WAITED_ON)
41+
3442
typedef struct _mp_obj_task_t {
3543
mp_pairheap_t pairheap;
3644
mp_obj_t coro;
3745
mp_obj_t data;
38-
mp_obj_t waiting;
39-
46+
mp_obj_t state;
4047
mp_obj_t ph_key;
4148
} mp_obj_task_t;
4249

@@ -146,9 +153,6 @@ STATIC const mp_obj_type_t task_queue_type = {
146153
/******************************************************************************/
147154
// Task class
148155

149-
// For efficiency, the task object is stored to the coro entry when the task is done.
150-
#define TASK_IS_DONE(task) ((task)->coro == MP_OBJ_FROM_PTR(task))
151-
152156
// This is the core uasyncio context with cur_task, _task_queue and CancelledError.
153157
STATIC mp_obj_t uasyncio_context = MP_OBJ_NULL;
154158

@@ -159,7 +163,7 @@ STATIC mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, const mp
159163
mp_pairheap_init_node(task_lt, &self->pairheap);
160164
self->coro = args[0];
161165
self->data = mp_const_none;
162-
self->waiting = mp_const_none;
166+
self->state = TASK_STATE_RUNNING_NOT_WAITED_ON;
163167
self->ph_key = MP_OBJ_NEW_SMALL_INT(0);
164168
if (n_args == 2) {
165169
uasyncio_context = args[1];
@@ -218,24 +222,6 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
218222
}
219223
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
220224

221-
STATIC mp_obj_t task_throw(mp_obj_t self_in, mp_obj_t value_in) {
222-
// This task raised an exception which was uncaught; handle that now.
223-
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
224-
// Set the data because it was cleared by the main scheduling loop.
225-
self->data = value_in;
226-
if (self->waiting == mp_const_none) {
227-
// Nothing await'ed on the task so call the exception handler.
228-
mp_obj_t _exc_context = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__exc_context));
229-
mp_obj_dict_store(_exc_context, MP_OBJ_NEW_QSTR(MP_QSTR_exception), value_in);
230-
mp_obj_dict_store(_exc_context, MP_OBJ_NEW_QSTR(MP_QSTR_future), self_in);
231-
mp_obj_t Loop = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_Loop));
232-
mp_obj_t call_exception_handler = mp_load_attr(Loop, MP_QSTR_call_exception_handler);
233-
mp_call_function_1(call_exception_handler, _exc_context);
234-
}
235-
return mp_const_none;
236-
}
237-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_throw_obj, task_throw);
238-
239225
STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
240226
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
241227
if (dest[0] == MP_OBJ_NULL) {
@@ -244,32 +230,24 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
244230
dest[0] = self->coro;
245231
} else if (attr == MP_QSTR_data) {
246232
dest[0] = self->data;
247-
} else if (attr == MP_QSTR_waiting) {
248-
if (self->waiting != mp_const_none && self->waiting != mp_const_false) {
249-
dest[0] = self->waiting;
250-
}
233+
} else if (attr == MP_QSTR_state) {
234+
dest[0] = self->state;
251235
} else if (attr == MP_QSTR_done) {
252236
dest[0] = MP_OBJ_FROM_PTR(&task_done_obj);
253237
dest[1] = self_in;
254238
} else if (attr == MP_QSTR_cancel) {
255239
dest[0] = MP_OBJ_FROM_PTR(&task_cancel_obj);
256240
dest[1] = self_in;
257-
} else if (attr == MP_QSTR_throw) {
258-
dest[0] = MP_OBJ_FROM_PTR(&task_throw_obj);
259-
dest[1] = self_in;
260241
} else if (attr == MP_QSTR_ph_key) {
261242
dest[0] = self->ph_key;
262243
}
263244
} else if (dest[1] != MP_OBJ_NULL) {
264245
// Store
265-
if (attr == MP_QSTR_coro) {
266-
self->coro = dest[1];
267-
dest[0] = MP_OBJ_NULL;
268-
} else if (attr == MP_QSTR_data) {
246+
if (attr == MP_QSTR_data) {
269247
self->data = dest[1];
270248
dest[0] = MP_OBJ_NULL;
271-
} else if (attr == MP_QSTR_waiting) {
272-
self->waiting = dest[1];
249+
} else if (attr == MP_QSTR_state) {
250+
self->state = dest[1];
273251
dest[0] = MP_OBJ_NULL;
274252
}
275253
}
@@ -278,15 +256,12 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
278256
STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
279257
(void)iter_buf;
280258
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
281-
if (self->waiting == mp_const_none) {
282-
// The is the first access of the "waiting" entry.
283-
if (TASK_IS_DONE(self)) {
284-
// Signal that the completed-task has been await'ed on.
285-
self->waiting = mp_const_false;
286-
} else {
287-
// Lazily allocate the waiting queue.
288-
self->waiting = task_queue_make_new(&task_queue_type, 0, 0, NULL);
289-
}
259+
if (TASK_IS_DONE(self)) {
260+
// Signal that the completed-task has been await'ed on.
261+
self->state = TASK_STATE_DONE_WAS_WAITED_ON;
262+
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
263+
// Allocate the waiting queue.
264+
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
290265
}
291266
return self_in;
292267
}
@@ -299,7 +274,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
299274
} else {
300275
// Put calling task on waiting queue.
301276
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
302-
mp_obj_t args[2] = { self->waiting, cur_task };
277+
mp_obj_t args[2] = { self->state, cur_task };
303278
task_queue_push_sorted(2, args);
304279
// Set calling task's data to this task that it waits on, to double-link it.
305280
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;

0 commit comments

Comments
 (0)