From da3caedc559d6314502ddc4b10cad8534fb9d8d1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 14 Jan 2008 21:39:24 +0000 Subject: Remove Queue.empty() and Queue.full() in favor of using qsize() or trapping the Empty and Full exceptions. --- Doc/library/queue.rst | 12 ------------ Lib/Queue.py | 48 ++++++++++++++---------------------------------- Lib/test/test_queue.py | 35 +++++++++++++++++++---------------- Lib/test/test_socket.py | 2 +- Misc/NEWS | 3 +++ 5 files changed, 37 insertions(+), 63 deletions(-) diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index e9da905..c5dbc20 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -53,18 +53,6 @@ See the source code for details. The public methods are: this number is not reliable. -.. method:: Queue.empty() - - Return ``True`` if the queue is empty, ``False`` otherwise. Because of - multithreading semantics, this is not reliable. - - -.. method:: Queue.full() - - Return ``True`` if the queue is full, ``False`` otherwise. Because of - multithreading semantics, this is not reliable. - - .. method:: Queue.put(item[, block[, timeout]]) Put *item* into the queue. If optional args *block* is true and *timeout* is diff --git a/Lib/Queue.py b/Lib/Queue.py index 79b0abf..726cf3e 100644 --- a/Lib/Queue.py +++ b/Lib/Queue.py @@ -23,6 +23,7 @@ class Queue: import threading except ImportError: import dummy_threading as threading + self.maxsize = maxsize self._init(maxsize) # mutex must be held whenever the queue is mutating. All methods # that acquire mutex must release it before returning. mutex @@ -88,20 +89,6 @@ class Queue: self.mutex.release() return n - def empty(self): - """Return True if the queue is empty, False otherwise (not reliable!).""" - self.mutex.acquire() - n = self._empty() - self.mutex.release() - return n - - def full(self): - """Return True if the queue is full, False otherwise (not reliable!).""" - self.mutex.acquire() - n = self._full() - self.mutex.release() - return n - def put(self, item, block=True, timeout=None): """Put an item into the queue. @@ -116,20 +103,22 @@ class Queue: self.not_full.acquire() try: if not block: - if self._full(): + if self.maxsize > 0 and self._qsize() == self.maxsize: raise Full elif timeout is None: - while self._full(): - self.not_full.wait() + if self.maxsize > 0: + while self._qsize() == self.maxsize: + self.not_full.wait() else: if timeout < 0: raise ValueError("'timeout' must be a positive number") endtime = _time() + timeout - while self._full(): - remaining = endtime - _time() - if remaining <= 0.0: - raise Full - self.not_full.wait(remaining) + if self.maxsize > 0: + while self._qsize() == self.maxsize: + remaining = endtime - _time() + if remaining <= 0.0: + raise Full + self.not_full.wait(remaining) self._put(item) self.unfinished_tasks += 1 self.not_empty.notify() @@ -158,16 +147,16 @@ class Queue: self.not_empty.acquire() try: if not block: - if self._empty(): + if not self._qsize(): raise Empty elif timeout is None: - while self._empty(): + while not self._qsize(): self.not_empty.wait() else: if timeout < 0: raise ValueError("'timeout' must be a positive number") endtime = _time() + timeout - while self._empty(): + while not self._qsize(): remaining = endtime - _time() if remaining <= 0.0: raise Empty @@ -192,20 +181,11 @@ class Queue: # Initialize the queue representation def _init(self, maxsize): - self.maxsize = maxsize self.queue = deque() def _qsize(self): return len(self.queue) - # Check whether the queue is empty - def _empty(self): - return not self.queue - - # Check whether the queue is full - def _full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - # Put a new item in the queue def _put(self, item): self.queue.append(item) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 0b2f31a..4d89ed2 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -9,6 +9,9 @@ from test.test_support import verify, TestFailed, verbose QUEUE_SIZE = 5 +def qfull(q): + return q.maxsize > 0 and q.qsize() == q.maxsize + # A thread to run a function that unclogs a blocked Queue. class _TriggerThread(threading.Thread): def __init__(self, fn, args): @@ -96,7 +99,7 @@ class FailingQueue(Queue.Queue): return Queue.Queue._get(self) def FailingQueueTest(q): - if not q.empty(): + if q.qsize(): raise RuntimeError("Call this function with an empty queue") for i in range(QUEUE_SIZE-1): q.put(i) @@ -114,7 +117,7 @@ def FailingQueueTest(q): except FailingQueueException: pass q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") # Test a failing blocking put q.fail_next_put = True try: @@ -136,17 +139,17 @@ def FailingQueueTest(q): # Check the Queue isn't damaged. # put failed, but get succeeded - re-add q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") q.get() - verify(not q.full(), "Queue should not be full") + verify(not qfull(q), "Queue should not be full") q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") # Test a blocking put _doBlockingTest( q.put, ("full",), q.get, ()) # Empty it for i in range(QUEUE_SIZE): q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") q.put("first") q.fail_next_get = True try: @@ -154,16 +157,16 @@ def FailingQueueTest(q): raise TestFailed("The queue didn't fail when it should have") except FailingQueueException: pass - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.fail_next_get = True try: q.get(timeout=0.1) raise TestFailed("The queue didn't fail when it should have") except FailingQueueException: pass - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") q.fail_next_get = True try: _doExceptionalBlockingTest(q.get, (), q.put, ('empty',), @@ -172,12 +175,12 @@ def FailingQueueTest(q): except FailingQueueException: pass # put succeeded, but get failed. - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") def SimpleQueueTest(q): - if not q.empty(): + if q.qsize(): raise RuntimeError("Call this function with an empty queue") # I guess we better check things actually queue correctly a little :) q.put(111) @@ -186,10 +189,10 @@ def SimpleQueueTest(q): "Didn't seem to queue the correct data!") for i in range(QUEUE_SIZE-1): q.put(i) - verify(not q.empty(), "Queue should not be empty") - verify(not q.full(), "Queue should not be full") + verify(q.qsize(), "Queue should not be empty") + verify(not qfull(q), "Queue should not be full") q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") try: q.put("full", block=0) raise TestFailed("Didn't appear to block with a full queue") @@ -206,7 +209,7 @@ def SimpleQueueTest(q): # Empty it for i in range(QUEUE_SIZE): q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") try: q.get(block=0) raise TestFailed("Didn't appear to block with an empty queue") diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index d474206..23b7759 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -118,7 +118,7 @@ class ThreadableTest: self.__tearDown() self.done.wait() - if not self.queue.empty(): + if self.queue.qsize(): msg = self.queue.get() self.fail(msg) diff --git a/Misc/NEWS b/Misc/NEWS index 9e9aaae..55ec387 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -352,6 +352,9 @@ Core and Builtins Library ------- +- Removed Queue.empty() and Queue.full(). Instead use Queue.qsize() or + trap the Empty and Full exceptions. + - Removed defunct parts of the random module (the Wichmann-Hill generator and the jumpahead() method). -- cgit v0.12