Skip to content

Commit c2f9259

Browse files
committed
ringbuf_queue raises IndexError. Fix gather error in tutorial.
1 parent 1a6b219 commit c2f9259

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

v3/docs/EVENTS.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,9 @@ Synchronous methods (immediate return):
500500
* `qsize` No arg. Returns the number of items in the queue.
501501
* `empty` No arg. Returns `True` if the queue is empty.
502502
* `full` No arg. Returns `True` if the queue is full.
503-
* `get_nowait` No arg. Returns an object from the queue. Raises an exception
503+
* `get_nowait` No arg. Returns an object from the queue. Raises `IndexError`
504504
if the queue is empty.
505-
* `put_nowait` Arg: the object to put on the queue. Raises an exception if the
505+
* `put_nowait` Arg: the object to put on the queue. Raises `IndexError` if the
506506
queue is full. If the calling code ignores the exception the oldest item in
507507
the queue will be overwritten. In some applications this can be of use.
508508

@@ -523,6 +523,17 @@ async def handle_queued_data(q):
523523
The `sleep` is necessary if you have multiple tasks waiting on the queue,
524524
otherwise one task hogs all the data.
525525

526+
The following illustrates putting items onto a `RingbufQueue` where the queue is
527+
not allowed to stall: where it becomes full, new items overwrite the oldest ones
528+
in the queue:
529+
```python
530+
def add_item(q, data):
531+
try:
532+
q.put_nowait(data)
533+
except IndexError:
534+
pass
535+
```
536+
526537
###### [Contents](./EVENTS.md#0-contents)
527538

528539
# 100 Appendix 1 Polling

v3/docs/TUTORIAL.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ cancellation or timeout. It returns a list of the return values of each task.
755755

756756
Its call signature is
757757
```python
758-
res = await asyncio.gather(*tasks, return_exceptions=True)
758+
res = await asyncio.gather(*tasks, return_exceptions=False)
759759
```
760760
The keyword-only boolean arg `return_exceptions` determines the behaviour in
761761
the event of a cancellation or timeout of tasks. If `False`, the `gather`
@@ -1095,10 +1095,25 @@ serviced the device, the ISR flags an asynchronous routine, typically
10951095
processing received data.
10961096

10971097
The fact that only one task may wait on a `ThreadSafeFlag` may be addressed by
1098-
having the task that waits on the `ThreadSafeFlag` set an `Event`. Multiple
1099-
tasks may wait on that `Event`. As an alternative to explicitly coding this,
1100-
the [Message class](./TUTORIAL.md#39-message) uses this approach to provide an
1101-
`Event`-like object which can be triggered from an ISR.
1098+
having a task that waits on the `ThreadSafeFlag` set an `Event` as in the
1099+
following:
1100+
```python
1101+
class ThreadSafeEvent(asyncio.Event):
1102+
def __init__(self):
1103+
super().__init__()
1104+
self._tsf = asyncio.ThreadSafeFlag()
1105+
asyncio.create_task(self._run())
1106+
1107+
async def _run(self):
1108+
while True:
1109+
await self._tsf.wait()
1110+
super().set()
1111+
1112+
def set(self):
1113+
self._tsf.set()
1114+
```
1115+
An instance may be set by a hard ISR or from another thread/core. It must
1116+
explicitly be cleared. Multiple tasks may wait on it.
11021117

11031118
###### [Contents](./TUTORIAL.md#contents)
11041119

v3/primitives/ringbuf_queue.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@
66

77
import uasyncio as asyncio
88

9-
# Exception raised by get_nowait().
10-
class QueueEmpty(Exception):
11-
pass
12-
13-
# Exception raised by put_nowait().
14-
class QueueFull(Exception):
15-
pass
169

1710
class RingbufQueue: # MicroPython optimised
1811
def __init__(self, buf):
@@ -35,7 +28,7 @@ def qsize(self):
3528
def get_nowait(self): # Remove and return an item from the queue.
3629
# Return an item if one is immediately available, else raise QueueEmpty.
3730
if self.empty():
38-
raise QueueEmpty()
31+
raise IndexError
3932
r = self._q[self._ri]
4033
self._ri = (self._ri + 1) % self._size
4134
return r
@@ -47,7 +40,7 @@ def put_nowait(self, v):
4740
self._wi = (self._wi + 1) % self._size
4841
if self._wi == self._ri: # Would indicate empty
4942
self._ri = (self._ri + 1) % self._size # Discard a message
50-
raise QueueFull # Caller can ignore if overwrites are OK
43+
raise IndexError # Caller can ignore if overwrites are OK
5144

5245
async def put(self, val): # Usage: await queue.put(item)
5346
while self.full(): # Queue full

v3/primitives/tests/asyntest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ async def rbq_go():
533533
for x in range(4, 15):
534534
try:
535535
q.put_nowait(x)
536-
except:
536+
except IndexError:
537537
nfail += 1
538538
assert nfail == 5
539539
assert q.full()

0 commit comments

Comments
 (0)