From db92aba496cf3bb8aded080eac68d76589621cfb Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 12 Aug 2025 19:56:17 +0100 Subject: [PATCH 1/3] Fix argument parsing for ``_interpqueues.put()`` --- Modules/_interpqueuesmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index e5afe746f90bdc..03ed081efbae0d 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1603,7 +1603,7 @@ queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds) PyObject *obj; int unboundarg = -1; int fallbackarg = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|ii$p:put", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|ii:put", kwlist, qidarg_converter, &qidarg, &obj, &unboundarg, &fallbackarg)) { From 8eca5cf56daf111fe1c4c496b0e325bad930fb08 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Wed, 13 Aug 2025 04:23:54 +0100 Subject: [PATCH 2/3] Serhiy's review --- Lib/concurrent/interpreters/_queues.py | 2 +- Lib/test/test_interpreters/test_queues.py | 33 ++++++++++++++++++----- Modules/_interpqueuesmodule.c | 4 +-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Lib/concurrent/interpreters/_queues.py b/Lib/concurrent/interpreters/_queues.py index 9c12b2c8c24664..8f2f1cb5753584 100644 --- a/Lib/concurrent/interpreters/_queues.py +++ b/Lib/concurrent/interpreters/_queues.py @@ -73,7 +73,7 @@ def create(maxsize=0, *, unbounditems=UNBOUND): """ unbound = _serialize_unbound(unbounditems) unboundop, = unbound - qid = _queues.create(maxsize, unboundop, -1) + qid = _queues.create(maxsize, unboundop) self = Queue(qid) self._set_unbound(unboundop, unbounditems) return self diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index 5451c6654acb47..742b253ac4b8ab 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -42,7 +42,7 @@ def test_highlevel_reloaded(self): importlib.reload(queues) def test_create_destroy(self): - qid = _queues.create(2, REPLACE, -1) + qid = _queues.create(2, REPLACE) _queues.destroy(qid) self.assertEqual(get_num_queues(), 0) with self.assertRaises(queues.QueueNotFoundError): @@ -56,7 +56,7 @@ def test_not_destroyed(self): '-c', dedent(f""" import {_queues.__name__} as _queues - _queues.create(2, {REPLACE}, -1) + _queues.create(2, {REPLACE}) """), ) self.assertEqual(stdout, '') @@ -67,13 +67,13 @@ def test_not_destroyed(self): def test_bind_release(self): with self.subTest('typical'): - qid = _queues.create(2, REPLACE, -1) + qid = _queues.create(2, REPLACE) _queues.bind(qid) _queues.release(qid) self.assertEqual(get_num_queues(), 0) with self.subTest('bind too much'): - qid = _queues.create(2, REPLACE, -1) + qid = _queues.create(2, REPLACE) _queues.bind(qid) _queues.bind(qid) _queues.release(qid) @@ -81,7 +81,7 @@ def test_bind_release(self): self.assertEqual(get_num_queues(), 0) with self.subTest('nested'): - qid = _queues.create(2, REPLACE, -1) + qid = _queues.create(2, REPLACE) _queues.bind(qid) _queues.bind(qid) _queues.release(qid) @@ -89,10 +89,31 @@ def test_bind_release(self): self.assertEqual(get_num_queues(), 0) with self.subTest('release without binding'): - qid = _queues.create(2, REPLACE, -1) + qid = _queues.create(2, REPLACE) with self.assertRaises(queues.QueueError): _queues.release(qid) + def test_parse_fallback(self): + # see https://github.com/python/cpython/pull/137686 + # does not raise TypeError / OverflowError / ValueError + for arg in False, True, None, -1, 2**1000: + _queues.create(2, REPLACE, fallback=arg) + msg = r'create\(\) takes at most 2 positional arguments' + with self.assertRaisesRegex(TypeError, msg): + _queues.create(2, REPLACE, -1) + + obj = None + unboundop = -1 + for arg in False, True, None, -1, 2**1000: + qid = _queues.create(2, REPLACE) + _queues.put(qid, obj, unboundop, fallback=arg) + _queues.destroy(qid) + msg = r'put\(\) takes at most 3 positional arguments' + with self.assertRaisesRegex(TypeError, msg): + qid = _queues.create(2, REPLACE) + _queues.put(qid, obj, unboundop, -1) + _queues.destroy(qid) + class QueueTests(TestBase): diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 03ed081efbae0d..8b177cbceb6927 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1486,7 +1486,7 @@ queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds) Py_ssize_t maxsize; int unboundarg = -1; int fallbackarg = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|ii:create", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|i$p:create", kwlist, &maxsize, &unboundarg, &fallbackarg)) { return NULL; @@ -1603,7 +1603,7 @@ queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds) PyObject *obj; int unboundarg = -1; int fallbackarg = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|ii:put", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|i$p:put", kwlist, qidarg_converter, &qidarg, &obj, &unboundarg, &fallbackarg)) { From 5e783c7528e9468900789c255053b96f364e9eea Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 21 Aug 2025 04:29:24 +0200 Subject: [PATCH 3/3] Eric's feedback --- Lib/concurrent/interpreters/_queues.py | 2 +- Lib/test/test_interpreters/test_queues.py | 33 +++++------------------ Modules/_interpqueuesmodule.c | 4 +-- 3 files changed, 9 insertions(+), 30 deletions(-) diff --git a/Lib/concurrent/interpreters/_queues.py b/Lib/concurrent/interpreters/_queues.py index 8f2f1cb5753584..9c12b2c8c24664 100644 --- a/Lib/concurrent/interpreters/_queues.py +++ b/Lib/concurrent/interpreters/_queues.py @@ -73,7 +73,7 @@ def create(maxsize=0, *, unbounditems=UNBOUND): """ unbound = _serialize_unbound(unbounditems) unboundop, = unbound - qid = _queues.create(maxsize, unboundop) + qid = _queues.create(maxsize, unboundop, -1) self = Queue(qid) self._set_unbound(unboundop, unbounditems) return self diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index 742b253ac4b8ab..5451c6654acb47 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -42,7 +42,7 @@ def test_highlevel_reloaded(self): importlib.reload(queues) def test_create_destroy(self): - qid = _queues.create(2, REPLACE) + qid = _queues.create(2, REPLACE, -1) _queues.destroy(qid) self.assertEqual(get_num_queues(), 0) with self.assertRaises(queues.QueueNotFoundError): @@ -56,7 +56,7 @@ def test_not_destroyed(self): '-c', dedent(f""" import {_queues.__name__} as _queues - _queues.create(2, {REPLACE}) + _queues.create(2, {REPLACE}, -1) """), ) self.assertEqual(stdout, '') @@ -67,13 +67,13 @@ def test_not_destroyed(self): def test_bind_release(self): with self.subTest('typical'): - qid = _queues.create(2, REPLACE) + qid = _queues.create(2, REPLACE, -1) _queues.bind(qid) _queues.release(qid) self.assertEqual(get_num_queues(), 0) with self.subTest('bind too much'): - qid = _queues.create(2, REPLACE) + qid = _queues.create(2, REPLACE, -1) _queues.bind(qid) _queues.bind(qid) _queues.release(qid) @@ -81,7 +81,7 @@ def test_bind_release(self): self.assertEqual(get_num_queues(), 0) with self.subTest('nested'): - qid = _queues.create(2, REPLACE) + qid = _queues.create(2, REPLACE, -1) _queues.bind(qid) _queues.bind(qid) _queues.release(qid) @@ -89,31 +89,10 @@ def test_bind_release(self): self.assertEqual(get_num_queues(), 0) with self.subTest('release without binding'): - qid = _queues.create(2, REPLACE) + qid = _queues.create(2, REPLACE, -1) with self.assertRaises(queues.QueueError): _queues.release(qid) - def test_parse_fallback(self): - # see https://github.com/python/cpython/pull/137686 - # does not raise TypeError / OverflowError / ValueError - for arg in False, True, None, -1, 2**1000: - _queues.create(2, REPLACE, fallback=arg) - msg = r'create\(\) takes at most 2 positional arguments' - with self.assertRaisesRegex(TypeError, msg): - _queues.create(2, REPLACE, -1) - - obj = None - unboundop = -1 - for arg in False, True, None, -1, 2**1000: - qid = _queues.create(2, REPLACE) - _queues.put(qid, obj, unboundop, fallback=arg) - _queues.destroy(qid) - msg = r'put\(\) takes at most 3 positional arguments' - with self.assertRaisesRegex(TypeError, msg): - qid = _queues.create(2, REPLACE) - _queues.put(qid, obj, unboundop, -1) - _queues.destroy(qid) - class QueueTests(TestBase): diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 8b177cbceb6927..03ed081efbae0d 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1486,7 +1486,7 @@ queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds) Py_ssize_t maxsize; int unboundarg = -1; int fallbackarg = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|i$p:create", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "n|ii:create", kwlist, &maxsize, &unboundarg, &fallbackarg)) { return NULL; @@ -1603,7 +1603,7 @@ queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds) PyObject *obj; int unboundarg = -1; int fallbackarg = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|i$p:put", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|ii:put", kwlist, qidarg_converter, &qidarg, &obj, &unboundarg, &fallbackarg)) {