Skip to content

Commit 666795a

Browse files
[3.13] pythongh-135698: Fix Cross-interpreter Queue.full() With Negative/Default max_size (pythongh-135778)
We weren't handling non-positive maxsize values (including the default) properly in Queue.full(). This change fixes that and adjusts an associated assert. (cherry picked from commit c5ea8e8, AKA pythongh-135724)
1 parent 3e81d56 commit 666795a

File tree

2 files changed

+62
-13
lines changed

2 files changed

+62
-13
lines changed

Lib/test/test_interpreters/test_queues.py

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,18 +209,64 @@ def test_empty(self):
209209
self.assertIs(after, True)
210210

211211
def test_full(self):
212-
expected = [False, False, False, True, False, False, False]
213-
actual = []
214-
queue = queues.create(3)
215-
for _ in range(3):
216-
actual.append(queue.full())
217-
queue.put(None, syncobj=True)
218-
actual.append(queue.full())
219-
for _ in range(3):
220-
queue.get()
221-
actual.append(queue.full())
212+
for maxsize in [1, 3, 11]:
213+
with self.subTest(f'maxsize={maxsize}'):
214+
num_to_add = maxsize
215+
expected = [False] * (num_to_add * 2 + 3)
216+
expected[maxsize] = True
217+
expected[maxsize + 1] = True
218+
219+
queue = queues.create(maxsize)
220+
actual = []
221+
empty = [queue.empty()]
222+
223+
for _ in range(num_to_add):
224+
actual.append(queue.full())
225+
queue.put_nowait(None)
226+
actual.append(queue.full())
227+
with self.assertRaises(queues.QueueFull):
228+
queue.put_nowait(None)
229+
empty.append(queue.empty())
230+
231+
for _ in range(num_to_add):
232+
actual.append(queue.full())
233+
queue.get_nowait()
234+
actual.append(queue.full())
235+
with self.assertRaises(queues.QueueEmpty):
236+
queue.get_nowait()
237+
actual.append(queue.full())
238+
empty.append(queue.empty())
222239

223-
self.assertEqual(actual, expected)
240+
self.assertEqual(actual, expected)
241+
self.assertEqual(empty, [True, False, True])
242+
243+
# no max size
244+
for args in [(), (0,), (-1,), (-10,)]:
245+
with self.subTest(f'maxsize={args[0]}' if args else '<default>'):
246+
num_to_add = 13
247+
expected = [False] * (num_to_add * 2 + 3)
248+
249+
queue = queues.create(*args)
250+
actual = []
251+
empty = [queue.empty()]
252+
253+
for _ in range(num_to_add):
254+
actual.append(queue.full())
255+
queue.put_nowait(None)
256+
actual.append(queue.full())
257+
empty.append(queue.empty())
258+
259+
for _ in range(num_to_add):
260+
actual.append(queue.full())
261+
queue.get_nowait()
262+
actual.append(queue.full())
263+
with self.assertRaises(queues.QueueEmpty):
264+
queue.get_nowait()
265+
actual.append(queue.full())
266+
empty.append(queue.empty())
267+
268+
self.assertEqual(actual, expected)
269+
self.assertEqual(empty, [True, False, True])
224270

225271
def test_qsize(self):
226272
expected = [0, 1, 2, 3, 2, 3, 2, 1, 0, 1, 0]

Modules/_interpqueuesmodule.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,11 @@ _queue_is_full(_queue *queue, int *p_is_full)
718718
return err;
719719
}
720720

721-
assert(queue->items.count <= queue->items.maxsize);
722-
*p_is_full = queue->items.count == queue->items.maxsize;
721+
assert(queue->items.maxsize <= 0
722+
|| queue->items.count <= queue->items.maxsize);
723+
*p_is_full = queue->items.maxsize > 0
724+
? queue->items.count == queue->items.maxsize
725+
: 0;
723726

724727
_queue_unlock(queue);
725728
return 0;

0 commit comments

Comments
 (0)