diff --git a/README.md b/README.md index 5ff32c9..780b5ed 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,10 @@ 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): @@ -46,7 +46,7 @@ async def consumer(q): while True: c = await q.get() print('consumed', c) - except (Closed, NothingLeft): + except Closed: pass ``` diff --git a/src/asynckivy_ext/queue.py b/src/asynckivy_ext/queue.py index a83e6f1..e4d82b5 100644 --- a/src/asynckivy_ext/queue.py +++ b/src/asynckivy_ext/queue.py @@ -1,5 +1,5 @@ __all__ = ( - 'QueueException', 'WouldBlock', 'Closed', 'NothingLeft', + 'QueueException', 'WouldBlock', 'Closed', 'Queue', 'Order', 'QueueState', ) import typing as T @@ -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'] @@ -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: @@ -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() @@ -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): ''' @@ -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): @@ -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: @@ -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() diff --git a/tests/test_queue.py b/tests/test_queue.py index e96ccdf..3ff38de 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -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()) @@ -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) @@ -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): @@ -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') @@ -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) @@ -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') @@ -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'