From: Serhiy Storchaka Date: Tue, 2 Sep 2025 05:59:20 +0000 (+0300) Subject: gh-138253: Fix compatibility of sub-interpreters queues with queue.Queue (GH-138256) X-Git-Tag: v3.15.0a1~540 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cb18269e1ba6f8e49307cb4f74832ae04fd3b6d3;p=thirdparty%2FPython%2Fcpython.git gh-138253: Fix compatibility of sub-interpreters queues with queue.Queue (GH-138256) Add the block parameter in the put() and get() methods of the concurrent.interpreters queues for compatibility with the queue.Queue interface. --- diff --git a/Lib/concurrent/interpreters/_queues.py b/Lib/concurrent/interpreters/_queues.py index 9c12b2c8c246..b5cc0b894494 100644 --- a/Lib/concurrent/interpreters/_queues.py +++ b/Lib/concurrent/interpreters/_queues.py @@ -170,13 +170,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 @@ -209,6 +209,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: @@ -235,17 +237,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: diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index 5451c6654acb..77334aea3836 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -11,7 +11,7 @@ from concurrent import interpreters from concurrent.interpreters import _queues as queues, _crossinterp from .utils import _run_output, TestBase as _TestBase - +HUGE_TIMEOUT = 3600 REPLACE = _crossinterp._UNBOUND_CONSTANT_TO_FLAG[_crossinterp.UNBOUND] @@ -306,6 +306,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) @@ -315,6 +317,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) @@ -345,11 +351,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 index 000000000000..be810b759f44 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-30-10-58-15.gh-issue-138253.9Ehj-N.rst @@ -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.