]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-135698: Fix Cross-interpreter Queue.full() With Negative/Default max_size...
authorEric Snow <ericsnowcurrently@gmail.com>
Mon, 23 Jun 2025 19:38:41 +0000 (13:38 -0600)
committerGitHub <noreply@github.com>
Mon, 23 Jun 2025 19:38:41 +0000 (19:38 +0000)
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 gh-135724)

Lib/test/test_interpreters/test_queues.py
Modules/_interpqueuesmodule.c

index cbe0d8caffdefaa9db76178a00e95ce6be471254..7858c4e602ce2bba562f16d7b0eae33ea5a68a15 100644 (file)
@@ -209,18 +209,64 @@ class TestQueueOps(TestBase):
         self.assertIs(after, True)
 
     def test_full(self):
-        expected = [False, False, False, True, False, False, False]
-        actual = []
-        queue = queues.create(3)
-        for _ in range(3):
-            actual.append(queue.full())
-            queue.put(None, syncobj=True)
-        actual.append(queue.full())
-        for _ in range(3):
-            queue.get()
-            actual.append(queue.full())
+        for maxsize in [1, 3, 11]:
+            with self.subTest(f'maxsize={maxsize}'):
+                num_to_add = maxsize
+                expected = [False] * (num_to_add * 2 + 3)
+                expected[maxsize] = True
+                expected[maxsize + 1] = True
+
+                queue = queues.create(maxsize)
+                actual = []
+                empty = [queue.empty()]
+
+                for _ in range(num_to_add):
+                    actual.append(queue.full())
+                    queue.put_nowait(None)
+                actual.append(queue.full())
+                with self.assertRaises(queues.QueueFull):
+                    queue.put_nowait(None)
+                empty.append(queue.empty())
+
+                for _ in range(num_to_add):
+                    actual.append(queue.full())
+                    queue.get_nowait()
+                actual.append(queue.full())
+                with self.assertRaises(queues.QueueEmpty):
+                    queue.get_nowait()
+                actual.append(queue.full())
+                empty.append(queue.empty())
 
-        self.assertEqual(actual, expected)
+                self.assertEqual(actual, expected)
+                self.assertEqual(empty, [True, False, True])
+
+        # no max size
+        for args in [(), (0,), (-1,), (-10,)]:
+            with self.subTest(f'maxsize={args[0]}' if args else '<default>'):
+                num_to_add = 13
+                expected = [False] * (num_to_add * 2 + 3)
+
+                queue = queues.create(*args)
+                actual = []
+                empty = [queue.empty()]
+
+                for _ in range(num_to_add):
+                    actual.append(queue.full())
+                    queue.put_nowait(None)
+                actual.append(queue.full())
+                empty.append(queue.empty())
+
+                for _ in range(num_to_add):
+                    actual.append(queue.full())
+                    queue.get_nowait()
+                actual.append(queue.full())
+                with self.assertRaises(queues.QueueEmpty):
+                    queue.get_nowait()
+                actual.append(queue.full())
+                empty.append(queue.empty())
+
+                self.assertEqual(actual, expected)
+                self.assertEqual(empty, [True, False, True])
 
     def test_qsize(self):
         expected = [0, 1, 2, 3, 2, 3, 2, 1, 0, 1, 0]
index 73f80fe3a1ef9be0c8e37a15a219f5463bd08d91..6f050a988b1426088302cd3c1797b54c86149c1b 100644 (file)
@@ -718,8 +718,11 @@ _queue_is_full(_queue *queue, int *p_is_full)
         return err;
     }
 
-    assert(queue->items.count <= queue->items.maxsize);
-    *p_is_full = queue->items.count == queue->items.maxsize;
+    assert(queue->items.maxsize <= 0
+           || queue->items.count <= queue->items.maxsize);
+    *p_is_full = queue->items.maxsize > 0
+        ? queue->items.count == queue->items.maxsize
+        : 0;
 
     _queue_unlock(queue);
     return 0;