Skip to content

Commit c5ea8e8

Browse files
gh-135698: Fix Cross-interpreter Queue.full() With Negative/Default max_size (gh-135724)
We weren't handling non-positive maxsize values (including the default) properly in Queue.full(). This change fixes that and adjusts an associated assert.
1 parent a8ec511 commit c5ea8e8

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
@@ -208,18 +208,64 @@ def test_empty(self):
208208
self.assertIs(after, True)
209209

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

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

224270
def test_qsize(self):
225271
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
@@ -707,8 +707,11 @@ _queue_is_full(_queue *queue, int *p_is_full)
707707
return err;
708708
}
709709

710-
assert(queue->items.count <= queue->items.maxsize);
711-
*p_is_full = queue->items.count == queue->items.maxsize;
710+
assert(queue->items.maxsize <= 0
711+
|| queue->items.count <= queue->items.maxsize);
712+
*p_is_full = queue->items.maxsize > 0
713+
? queue->items.count == queue->items.maxsize
714+
: 0;
712715

713716
_queue_unlock(queue);
714717
return 0;

0 commit comments

Comments
 (0)