Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
(api-break) remove the NothingLeft exception
Browse files Browse the repository at this point in the history
  • Loading branch information
gottadiveintopython committed Dec 5, 2023
1 parent bf63130 commit e86f1b5
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 31 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ produced C
consumed C
```

``consumer()`` can be written in more primitive way:
The ``consumer()`` above can be written in more primitive way:

```python
from asynckivy_ext.queue import Closed, NothingLeft
from asynckivy_ext.queue import Closed


async def consumer(q):
try:
while True:
c = await q.get()
print('consumed', c)
except (Closed, NothingLeft):
except Closed:
pass
```

Expand Down
20 changes: 8 additions & 12 deletions src/asynckivy_ext/queue.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__all__ = (
'QueueException', 'WouldBlock', 'Closed', 'NothingLeft',
'QueueException', 'WouldBlock', 'Closed',
'Queue', 'Order', 'QueueState',
)
import typing as T
Expand Down Expand Up @@ -53,13 +53,10 @@ class Closed(QueueException):
* one tries to get an item from a queue that is in the ``CLOSED`` state.
* one tries to put an item into a queue that is in the ``CLOSED`` state.
* one tries to put an item into a queue that is in the ``HALF_CLOSED`` state.
* one tries to get an item from an **empty** queue that is in the ``HALF_CLOSED`` state.
'''


class NothingLeft(QueueException):
'''Occurs when one tries to get an item from an empty queue that is in the ``HALF_CLOSED`` state. '''


Item = T.Any
Order = T.Literal['fifo', 'lifo', 'small-first']

Expand Down Expand Up @@ -131,7 +128,7 @@ def get(self) -> T.Awaitable[Item]:
if self._state is QueueState.CLOSED:
raise Closed
if self._state is QueueState.HALF_CLOSED and self.is_empty:
raise NothingLeft
raise Closed
self._trigger_consume()
task = (yield _current_task)[0][0] # 本来は except-Cancelled節に置きたい文だが、そこでは yield が使えないので仕方がない
try:
Expand All @@ -145,7 +142,7 @@ def get_nowait(self) -> Item:
raise Closed
if self.is_empty:
if self._state is QueueState.HALF_CLOSED:
raise NothingLeft
raise Closed
raise WouldBlock
self._trigger_consume()
return self._c_get()
Expand Down Expand Up @@ -181,14 +178,13 @@ def half_close(self):
pop_putter = self._pop_putter
pop_getter = self._pop_getter
C = Closed
NL = NothingLeft

while (putter := pop_putter()[0]) is not None:
putter._throw_exc(C)
if not self.is_empty:
return
while (getter := pop_getter()) is not None:
getter._throw_exc(NL)
getter._throw_exc(C)

def close(self):
'''
Expand All @@ -214,7 +210,7 @@ async def __aiter__(self):
try:
while True:
yield await self.get()
except (NothingLeft, Closed):
except Closed:
pass

def _consume(self, dt):
Expand All @@ -225,7 +221,7 @@ def _consume(self, dt):
pop_getter = self._pop_getter
c_put = self._c_put
c_get = self._c_get
NL = NothingLeft
Closed_ = Closed
HALF_CLOSED = QueueState.HALF_CLOSED

while True:
Expand All @@ -245,7 +241,7 @@ def _consume(self, dt):
else:
if self._state is HALF_CLOSED:
while (getter := pop_getter()) is not None:
getter._throw_exc(NL)
getter._throw_exc(Closed_)
if (not putters) or self.is_full:
break
self._trigger_consume.cancel()
Expand Down
25 changes: 9 additions & 16 deletions tests/test_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,10 @@ def test_put_to_closed_queue(capacity, close, nowait):
@p('nowait', [True, False, ])
def test_get_to_closed_queue(capacity, close, nowait):
import asynckivy as ak
from asynckivy_ext.queue import Queue, Closed, NothingLeft
from asynckivy_ext.queue import Queue, Closed
q = Queue(capacity=capacity)
if close:
q.close()
exc = Closed
else:
q.half_close()
exc = NothingLeft
with pytest.raises(exc):
q.close() if close else q.half_close()
with pytest.raises(Closed):
q.get_nowait() if nowait else ak.start(q.get())


Expand Down Expand Up @@ -176,13 +171,13 @@ async def consumer(q):
@p_capacity2
def test_close_a_queue_while_it_holding_putters_and_getters(n_producers, n_consumers, close, capacity):
import asynckivy as ak
from asynckivy_ext.queue import Queue, Closed, NothingLeft
from asynckivy_ext.queue import Queue, Closed

async def producer(q):
with pytest.raises(Closed):
await q.put(None)
async def consumer(q):
with pytest.raises(Closed if close else NothingLeft):
with pytest.raises(Closed):
await q.get()

q = Queue(capacity=capacity)
Expand Down Expand Up @@ -274,7 +269,6 @@ def test_various_statistics_nowait(order):

@p_capacity
def test_get_nowait_while_there_are_no_putters_and_no_items(capacity):
import asynckivy as ak
from asynckivy_ext.queue import Queue, WouldBlock
q = Queue(capacity=capacity)
with pytest.raises(WouldBlock):
Expand Down Expand Up @@ -340,7 +334,7 @@ def test_put_nowait_to_unbounded_queue_that_has_a_getter():
@p_capacity2
def test_putter_triggers_close(kivy_clock, close, capacity):
import asynckivy as ak
from asynckivy_ext.queue import Queue, Closed, NothingLeft
from asynckivy_ext.queue import Queue, Closed

async def producer1(q):
await q.put('A')
Expand All @@ -355,8 +349,7 @@ async def consumer1(q):
else:
assert await q.get() == 'A'
async def consumer2(q):
exc = Closed if close else NothingLeft
with pytest.raises(exc):
with pytest.raises(Closed):
await q.get()

q = Queue(capacity=capacity)
Expand All @@ -379,7 +372,7 @@ async def consumer2(q):
@p_capacity2
def test_getter_triggers_close(kivy_clock, close, capacity):
import asynckivy as ak
from asynckivy_ext.queue import Queue, Closed, NothingLeft
from asynckivy_ext.queue import Queue, Closed

async def producer1(q):
await q.put('A')
Expand All @@ -397,7 +390,7 @@ async def consumer2(q):
with pytest.raises(Closed):
await q.get()
elif capacity is not None and capacity < 2:
with pytest.raises(NothingLeft):
with pytest.raises(Closed):
await q.get()
else:
assert await q.get() == 'B'
Expand Down

0 comments on commit e86f1b5

Please sign in to comment.