]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-138253: Fix compatibility of sub-interpreters queues with queue.Queue ...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 8 Sep 2025 15:37:39 +0000 (17:37 +0200)
committerGitHub <noreply@github.com>
Mon, 8 Sep 2025 15:37:39 +0000 (18:37 +0300)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/concurrent/interpreters/_queues.py
Lib/test/test_interpreters/test_queues.py
Misc/NEWS.d/next/Library/2025-08-30-10-58-15.gh-issue-138253.9Ehj-N.rst [new file with mode: 0644]

index ee830973f2a36e934688ef930bfaf4f513cec601..81ea1098d7f9f317d82db2b29c23d38f010e8a09 100644 (file)
@@ -171,13 +171,13 @@ class Queue:
     def qsize(self):
         return _queues.get_count(self._id)
 
-    def put(self, obj, timeout=None, *,
+    def put(self, obj, block=True, timeout=None, *,
             unbounditems=None,
             _delay=10 / 1000,  # 10 milliseconds
             ):
         """Add the object to the queue.
 
-        This blocks while the queue is full.
+        If "block" is true, this blocks while the queue is full.
 
         For most objects, the object received through Queue.get() will
         be a new one, equivalent to the original and not sharing any
@@ -210,6 +210,8 @@ class Queue:
         If "unbounditems" is UNBOUND then it is returned by get() in place
         of the unbound item.
         """
+        if not block:
+            return self.put_nowait(obj, unbounditems=unbounditems)
         if unbounditems is None:
             unboundop = -1
         else:
@@ -236,17 +238,19 @@ class Queue:
             unboundop, = _serialize_unbound(unbounditems)
         _queues.put(self._id, obj, unboundop)
 
-    def get(self, timeout=None, *,
+    def get(self, block=True, timeout=None, *,
             _delay=10 / 1000,  # 10 milliseconds
             ):
         """Return the next object from the queue.
 
-        This blocks while the queue is empty.
+        If "block" is true, this blocks while the queue is empty.
 
         If the next item's original interpreter has been destroyed
         then the "next object" is determined by the value of the
         "unbounditems" argument to put().
         """
+        if not block:
+            return self.get_nowait()
         if timeout is not None:
             timeout = int(timeout)
             if timeout < 0:
index 815d38d8bd7a4a0f94346cac995b6a126ad7a84c..8c6a0efbb920d82544440458c1fbe4f567825aaa 100644 (file)
@@ -12,7 +12,7 @@ from concurrent.interpreters import _queues as queues, _crossinterp
 import test._crossinterp_definitions as defs
 from .utils import _run_output, TestBase as _TestBase
 
-
+HUGE_TIMEOUT = 3600
 REPLACE = _crossinterp._UNBOUND_CONSTANT_TO_FLAG[_crossinterp.UNBOUND]
 
 
@@ -307,6 +307,8 @@ class TestQueueOps(TestBase):
         queue.put(None)
         with self.assertRaises(queues.QueueFull):
             queue.put(None, timeout=0.1)
+        with self.assertRaises(queues.QueueFull):
+            queue.put(None, HUGE_TIMEOUT, 0.1)
         queue.get()
         queue.put(None)
 
@@ -316,6 +318,10 @@ class TestQueueOps(TestBase):
         queue.put_nowait(None)
         with self.assertRaises(queues.QueueFull):
             queue.put_nowait(None)
+        with self.assertRaises(queues.QueueFull):
+            queue.put(None, False)
+        with self.assertRaises(queues.QueueFull):
+            queue.put(None, False, timeout=HUGE_TIMEOUT)
         queue.get()
         queue.put_nowait(None)
 
@@ -346,11 +352,17 @@ class TestQueueOps(TestBase):
         queue = queues.create()
         with self.assertRaises(queues.QueueEmpty):
             queue.get(timeout=0.1)
+        with self.assertRaises(queues.QueueEmpty):
+            queue.get(HUGE_TIMEOUT, 0.1)
 
     def test_get_nowait(self):
         queue = queues.create()
         with self.assertRaises(queues.QueueEmpty):
             queue.get_nowait()
+        with self.assertRaises(queues.QueueEmpty):
+            queue.get(False)
+        with self.assertRaises(queues.QueueEmpty):
+            queue.get(False, timeout=HUGE_TIMEOUT)
 
     def test_put_get_full_fallback(self):
         expected = list(range(20))
diff --git a/Misc/NEWS.d/next/Library/2025-08-30-10-58-15.gh-issue-138253.9Ehj-N.rst b/Misc/NEWS.d/next/Library/2025-08-30-10-58-15.gh-issue-138253.9Ehj-N.rst
new file mode 100644 (file)
index 0000000..be810b7
--- /dev/null
@@ -0,0 +1,3 @@
+Add the *block* parameter in the :meth:`!put` and :meth:`!get` methods
+of the :mod:`concurrent.interpreters` queues for compatibility with the
+:class:`queue.Queue` interface.