Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f75d4a7

Browse files
committed
Fix asyncio issue 235 (merge from 3.4).
2 parents 629d697 + 0bd16bc commit f75d4a7

3 files changed

Lines changed: 36 additions & 11 deletions

File tree

Lib/asyncio/queues.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def __init__(self, maxsize=0, *, loop=None):
5353
self._finished.set()
5454
self._init(maxsize)
5555

56+
# These three are overridable in subclasses.
57+
5658
def _init(self, maxsize):
5759
self._queue = collections.deque()
5860

@@ -61,6 +63,11 @@ def _get(self):
6163

6264
def _put(self, item):
6365
self._queue.append(item)
66+
67+
# End of the overridable methods.
68+
69+
def __put_internal(self, item):
70+
self._put(item)
6471
self._unfinished_tasks += 1
6572
self._finished.clear()
6673

@@ -132,7 +139,7 @@ def put(self, item):
132139
'queue non-empty, why are getters waiting?')
133140

134141
getter = self._getters.popleft()
135-
self._put(item)
142+
self.__put_internal(item)
136143

137144
# getter cannot be cancelled, we just removed done getters
138145
getter.set_result(self._get())
@@ -144,7 +151,7 @@ def put(self, item):
144151
yield from waiter
145152

146153
else:
147-
self._put(item)
154+
self.__put_internal(item)
148155

149156
def put_nowait(self, item):
150157
"""Put an item into the queue without blocking.
@@ -157,15 +164,15 @@ def put_nowait(self, item):
157164
'queue non-empty, why are getters waiting?')
158165

159166
getter = self._getters.popleft()
160-
self._put(item)
167+
self.__put_internal(item)
161168

162169
# getter cannot be cancelled, we just removed done getters
163170
getter.set_result(self._get())
164171

165172
elif self._maxsize > 0 and self._maxsize <= self.qsize():
166173
raise QueueFull
167174
else:
168-
self._put(item)
175+
self.__put_internal(item)
169176

170177
@coroutine
171178
def get(self):
@@ -179,7 +186,7 @@ def get(self):
179186
if self._putters:
180187
assert self.full(), 'queue not full, why are putters waiting?'
181188
item, putter = self._putters.popleft()
182-
self._put(item)
189+
self.__put_internal(item)
183190

184191
# When a getter runs and frees up a slot so this putter can
185192
# run, we need to defer the put for a tick to ensure that
@@ -206,7 +213,7 @@ def get_nowait(self):
206213
if self._putters:
207214
assert self.full(), 'queue not full, why are putters waiting?'
208215
item, putter = self._putters.popleft()
209-
self._put(item)
216+
self.__put_internal(item)
210217
# Wake putter on next tick.
211218

212219
# getter cannot be cancelled, we just removed done putters

Lib/test/test_asyncio/test_queues.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,14 +408,16 @@ def test_order(self):
408408
self.assertEqual([1, 2, 3], items)
409409

410410

411-
class QueueJoinTests(_QueueTestBase):
411+
class _QueueJoinTestMixin:
412+
413+
q_class = None
412414

413415
def test_task_done_underflow(self):
414-
q = asyncio.Queue(loop=self.loop)
416+
q = self.q_class(loop=self.loop)
415417
self.assertRaises(ValueError, q.task_done)
416418

417419
def test_task_done(self):
418-
q = asyncio.Queue(loop=self.loop)
420+
q = self.q_class(loop=self.loop)
419421
for i in range(100):
420422
q.put_nowait(i)
421423

@@ -452,7 +454,7 @@ def test():
452454
self.loop.run_until_complete(asyncio.wait(tasks, loop=self.loop))
453455

454456
def test_join_empty_queue(self):
455-
q = asyncio.Queue(loop=self.loop)
457+
q = self.q_class(loop=self.loop)
456458

457459
# Test that a queue join()s successfully, and before anything else
458460
# (done twice for insurance).
@@ -465,12 +467,24 @@ def join():
465467
self.loop.run_until_complete(join())
466468

467469
def test_format(self):
468-
q = asyncio.Queue(loop=self.loop)
470+
q = self.q_class(loop=self.loop)
469471
self.assertEqual(q._format(), 'maxsize=0')
470472

471473
q._unfinished_tasks = 2
472474
self.assertEqual(q._format(), 'maxsize=0 tasks=2')
473475

474476

477+
class QueueJoinTests(_QueueJoinTestMixin, _QueueTestBase):
478+
q_class = asyncio.Queue
479+
480+
481+
class LifoQueueJoinTests(_QueueJoinTestMixin, _QueueTestBase):
482+
q_class = asyncio.LifoQueue
483+
484+
485+
class PriorityQueueJoinTests(_QueueJoinTestMixin, _QueueTestBase):
486+
q_class = asyncio.PriorityQueue
487+
488+
475489
if __name__ == '__main__':
476490
unittest.main()

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ Core and Builtins
4949
Library
5050
-------
5151

52+
- Fix asyncio issue 235: LifoQueue and PriorityQueue's put didn't
53+
increment unfinished tasks (this bug was introduced when
54+
JoinableQueue was merged with Queue).
55+
5256
- Issue #23908: os functions now reject paths with embedded null character
5357
on Windows instead of silently truncate them.
5458

0 commit comments

Comments
 (0)