Remove Queue.empty() and Queue.full() in favor of using qsize() or trapping the Empty and Full exceptions.
This commit is contained in:
parent
d32ed6f511
commit
da3caedc55
@ -53,18 +53,6 @@ See the source code for details. The public methods are:
|
|||||||
this number is not reliable.
|
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]])
|
.. method:: Queue.put(item[, block[, timeout]])
|
||||||
|
|
||||||
Put *item* into the queue. If optional args *block* is true and *timeout* is
|
Put *item* into the queue. If optional args *block* is true and *timeout* is
|
||||||
|
48
Lib/Queue.py
48
Lib/Queue.py
@ -23,6 +23,7 @@ class Queue:
|
|||||||
import threading
|
import threading
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import dummy_threading as threading
|
import dummy_threading as threading
|
||||||
|
self.maxsize = maxsize
|
||||||
self._init(maxsize)
|
self._init(maxsize)
|
||||||
# mutex must be held whenever the queue is mutating. All methods
|
# mutex must be held whenever the queue is mutating. All methods
|
||||||
# that acquire mutex must release it before returning. mutex
|
# that acquire mutex must release it before returning. mutex
|
||||||
@ -88,20 +89,6 @@ class Queue:
|
|||||||
self.mutex.release()
|
self.mutex.release()
|
||||||
return n
|
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):
|
def put(self, item, block=True, timeout=None):
|
||||||
"""Put an item into the queue.
|
"""Put an item into the queue.
|
||||||
|
|
||||||
@ -116,20 +103,22 @@ class Queue:
|
|||||||
self.not_full.acquire()
|
self.not_full.acquire()
|
||||||
try:
|
try:
|
||||||
if not block:
|
if not block:
|
||||||
if self._full():
|
if self.maxsize > 0 and self._qsize() == self.maxsize:
|
||||||
raise Full
|
raise Full
|
||||||
elif timeout is None:
|
elif timeout is None:
|
||||||
while self._full():
|
if self.maxsize > 0:
|
||||||
self.not_full.wait()
|
while self._qsize() == self.maxsize:
|
||||||
|
self.not_full.wait()
|
||||||
else:
|
else:
|
||||||
if timeout < 0:
|
if timeout < 0:
|
||||||
raise ValueError("'timeout' must be a positive number")
|
raise ValueError("'timeout' must be a positive number")
|
||||||
endtime = _time() + timeout
|
endtime = _time() + timeout
|
||||||
while self._full():
|
if self.maxsize > 0:
|
||||||
remaining = endtime - _time()
|
while self._qsize() == self.maxsize:
|
||||||
if remaining <= 0.0:
|
remaining = endtime - _time()
|
||||||
raise Full
|
if remaining <= 0.0:
|
||||||
self.not_full.wait(remaining)
|
raise Full
|
||||||
|
self.not_full.wait(remaining)
|
||||||
self._put(item)
|
self._put(item)
|
||||||
self.unfinished_tasks += 1
|
self.unfinished_tasks += 1
|
||||||
self.not_empty.notify()
|
self.not_empty.notify()
|
||||||
@ -158,16 +147,16 @@ class Queue:
|
|||||||
self.not_empty.acquire()
|
self.not_empty.acquire()
|
||||||
try:
|
try:
|
||||||
if not block:
|
if not block:
|
||||||
if self._empty():
|
if not self._qsize():
|
||||||
raise Empty
|
raise Empty
|
||||||
elif timeout is None:
|
elif timeout is None:
|
||||||
while self._empty():
|
while not self._qsize():
|
||||||
self.not_empty.wait()
|
self.not_empty.wait()
|
||||||
else:
|
else:
|
||||||
if timeout < 0:
|
if timeout < 0:
|
||||||
raise ValueError("'timeout' must be a positive number")
|
raise ValueError("'timeout' must be a positive number")
|
||||||
endtime = _time() + timeout
|
endtime = _time() + timeout
|
||||||
while self._empty():
|
while not self._qsize():
|
||||||
remaining = endtime - _time()
|
remaining = endtime - _time()
|
||||||
if remaining <= 0.0:
|
if remaining <= 0.0:
|
||||||
raise Empty
|
raise Empty
|
||||||
@ -192,20 +181,11 @@ class Queue:
|
|||||||
|
|
||||||
# Initialize the queue representation
|
# Initialize the queue representation
|
||||||
def _init(self, maxsize):
|
def _init(self, maxsize):
|
||||||
self.maxsize = maxsize
|
|
||||||
self.queue = deque()
|
self.queue = deque()
|
||||||
|
|
||||||
def _qsize(self):
|
def _qsize(self):
|
||||||
return len(self.queue)
|
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
|
# Put a new item in the queue
|
||||||
def _put(self, item):
|
def _put(self, item):
|
||||||
self.queue.append(item)
|
self.queue.append(item)
|
||||||
|
@ -9,6 +9,9 @@ from test.test_support import verify, TestFailed, verbose
|
|||||||
|
|
||||||
QUEUE_SIZE = 5
|
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.
|
# A thread to run a function that unclogs a blocked Queue.
|
||||||
class _TriggerThread(threading.Thread):
|
class _TriggerThread(threading.Thread):
|
||||||
def __init__(self, fn, args):
|
def __init__(self, fn, args):
|
||||||
@ -96,7 +99,7 @@ class FailingQueue(Queue.Queue):
|
|||||||
return Queue.Queue._get(self)
|
return Queue.Queue._get(self)
|
||||||
|
|
||||||
def FailingQueueTest(q):
|
def FailingQueueTest(q):
|
||||||
if not q.empty():
|
if q.qsize():
|
||||||
raise RuntimeError("Call this function with an empty queue")
|
raise RuntimeError("Call this function with an empty queue")
|
||||||
for i in range(QUEUE_SIZE-1):
|
for i in range(QUEUE_SIZE-1):
|
||||||
q.put(i)
|
q.put(i)
|
||||||
@ -114,7 +117,7 @@ def FailingQueueTest(q):
|
|||||||
except FailingQueueException:
|
except FailingQueueException:
|
||||||
pass
|
pass
|
||||||
q.put("last")
|
q.put("last")
|
||||||
verify(q.full(), "Queue should be full")
|
verify(qfull(q), "Queue should be full")
|
||||||
# Test a failing blocking put
|
# Test a failing blocking put
|
||||||
q.fail_next_put = True
|
q.fail_next_put = True
|
||||||
try:
|
try:
|
||||||
@ -136,17 +139,17 @@ def FailingQueueTest(q):
|
|||||||
# Check the Queue isn't damaged.
|
# Check the Queue isn't damaged.
|
||||||
# put failed, but get succeeded - re-add
|
# put failed, but get succeeded - re-add
|
||||||
q.put("last")
|
q.put("last")
|
||||||
verify(q.full(), "Queue should be full")
|
verify(qfull(q), "Queue should be full")
|
||||||
q.get()
|
q.get()
|
||||||
verify(not q.full(), "Queue should not be full")
|
verify(not qfull(q), "Queue should not be full")
|
||||||
q.put("last")
|
q.put("last")
|
||||||
verify(q.full(), "Queue should be full")
|
verify(qfull(q), "Queue should be full")
|
||||||
# Test a blocking put
|
# Test a blocking put
|
||||||
_doBlockingTest( q.put, ("full",), q.get, ())
|
_doBlockingTest( q.put, ("full",), q.get, ())
|
||||||
# Empty it
|
# Empty it
|
||||||
for i in range(QUEUE_SIZE):
|
for i in range(QUEUE_SIZE):
|
||||||
q.get()
|
q.get()
|
||||||
verify(q.empty(), "Queue should be empty")
|
verify(not q.qsize(), "Queue should be empty")
|
||||||
q.put("first")
|
q.put("first")
|
||||||
q.fail_next_get = True
|
q.fail_next_get = True
|
||||||
try:
|
try:
|
||||||
@ -154,16 +157,16 @@ def FailingQueueTest(q):
|
|||||||
raise TestFailed("The queue didn't fail when it should have")
|
raise TestFailed("The queue didn't fail when it should have")
|
||||||
except FailingQueueException:
|
except FailingQueueException:
|
||||||
pass
|
pass
|
||||||
verify(not q.empty(), "Queue should not be empty")
|
verify(q.qsize(), "Queue should not be empty")
|
||||||
q.fail_next_get = True
|
q.fail_next_get = True
|
||||||
try:
|
try:
|
||||||
q.get(timeout=0.1)
|
q.get(timeout=0.1)
|
||||||
raise TestFailed("The queue didn't fail when it should have")
|
raise TestFailed("The queue didn't fail when it should have")
|
||||||
except FailingQueueException:
|
except FailingQueueException:
|
||||||
pass
|
pass
|
||||||
verify(not q.empty(), "Queue should not be empty")
|
verify(q.qsize(), "Queue should not be empty")
|
||||||
q.get()
|
q.get()
|
||||||
verify(q.empty(), "Queue should be empty")
|
verify(not q.qsize(), "Queue should be empty")
|
||||||
q.fail_next_get = True
|
q.fail_next_get = True
|
||||||
try:
|
try:
|
||||||
_doExceptionalBlockingTest(q.get, (), q.put, ('empty',),
|
_doExceptionalBlockingTest(q.get, (), q.put, ('empty',),
|
||||||
@ -172,12 +175,12 @@ def FailingQueueTest(q):
|
|||||||
except FailingQueueException:
|
except FailingQueueException:
|
||||||
pass
|
pass
|
||||||
# put succeeded, but get failed.
|
# put succeeded, but get failed.
|
||||||
verify(not q.empty(), "Queue should not be empty")
|
verify(q.qsize(), "Queue should not be empty")
|
||||||
q.get()
|
q.get()
|
||||||
verify(q.empty(), "Queue should be empty")
|
verify(not q.qsize(), "Queue should be empty")
|
||||||
|
|
||||||
def SimpleQueueTest(q):
|
def SimpleQueueTest(q):
|
||||||
if not q.empty():
|
if q.qsize():
|
||||||
raise RuntimeError("Call this function with an empty queue")
|
raise RuntimeError("Call this function with an empty queue")
|
||||||
# I guess we better check things actually queue correctly a little :)
|
# I guess we better check things actually queue correctly a little :)
|
||||||
q.put(111)
|
q.put(111)
|
||||||
@ -186,10 +189,10 @@ def SimpleQueueTest(q):
|
|||||||
"Didn't seem to queue the correct data!")
|
"Didn't seem to queue the correct data!")
|
||||||
for i in range(QUEUE_SIZE-1):
|
for i in range(QUEUE_SIZE-1):
|
||||||
q.put(i)
|
q.put(i)
|
||||||
verify(not q.empty(), "Queue should not be empty")
|
verify(q.qsize(), "Queue should not be empty")
|
||||||
verify(not q.full(), "Queue should not be full")
|
verify(not qfull(q), "Queue should not be full")
|
||||||
q.put("last")
|
q.put("last")
|
||||||
verify(q.full(), "Queue should be full")
|
verify(qfull(q), "Queue should be full")
|
||||||
try:
|
try:
|
||||||
q.put("full", block=0)
|
q.put("full", block=0)
|
||||||
raise TestFailed("Didn't appear to block with a full queue")
|
raise TestFailed("Didn't appear to block with a full queue")
|
||||||
@ -206,7 +209,7 @@ def SimpleQueueTest(q):
|
|||||||
# Empty it
|
# Empty it
|
||||||
for i in range(QUEUE_SIZE):
|
for i in range(QUEUE_SIZE):
|
||||||
q.get()
|
q.get()
|
||||||
verify(q.empty(), "Queue should be empty")
|
verify(not q.qsize(), "Queue should be empty")
|
||||||
try:
|
try:
|
||||||
q.get(block=0)
|
q.get(block=0)
|
||||||
raise TestFailed("Didn't appear to block with an empty queue")
|
raise TestFailed("Didn't appear to block with an empty queue")
|
||||||
|
@ -118,7 +118,7 @@ class ThreadableTest:
|
|||||||
self.__tearDown()
|
self.__tearDown()
|
||||||
self.done.wait()
|
self.done.wait()
|
||||||
|
|
||||||
if not self.queue.empty():
|
if self.queue.qsize():
|
||||||
msg = self.queue.get()
|
msg = self.queue.get()
|
||||||
self.fail(msg)
|
self.fail(msg)
|
||||||
|
|
||||||
|
@ -352,6 +352,9 @@ Core and Builtins
|
|||||||
Library
|
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
|
- Removed defunct parts of the random module (the Wichmann-Hill generator
|
||||||
and the jumpahead() method).
|
and the jumpahead() method).
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user