From 4d03baf997b08be15b458b22c6bc10fea2d2bcae Mon Sep 17 00:00:00 2001 From: Aniket Singh Yadav Date: Wed, 24 Dec 2025 17:19:11 +0530 Subject: [PATCH 01/10] implement __sizeof__ for SimpleQueue to account for ring-buffer storage --- Lib/test/test_queue.py | 11 +++++++++++ Modules/_queuemodule.c | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index c855fb8fe2b05a..d53787e98e35ea 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -9,6 +9,7 @@ from test.support import gc_collect, bigmemtest from test.support import import_helper from test.support import threading_helper +import ctypes # queue module depends on threading primitives threading_helper.requires_working_threading(module=True) @@ -1031,6 +1032,16 @@ def test_is_default(self): self.assertIs(self.type2test, self.queue.SimpleQueue) self.assertIs(self.type2test, self.queue.SimpleQueue) + def test_simplequeue_sizeof_reflects_buffer_growth(self): + q = self.type2test() + before = q.__sizeof__() + for _ in range(1000): + q.put(object()) + after = q.__sizeof__() + self.assertGreater(after, before) + ptr = ctypes.sizeof(ctypes.c_void_p) + self.assertEqual((after - before) % ptr, 0) + def test_reentrancy(self): # bpo-14976: put() may be called reentrantly in an asynchronous # callback. diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 01235c77bd7db8..614f566649b144 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -238,6 +238,18 @@ simplequeue_traverse(PyObject *op, visitproc visit, void *arg) Py_VISIT(Py_TYPE(self)); return 0; } +static PyObject * +simplequeue_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored)) +{ + simplequeueobject *self = simplequeueobject_CAST(op); + Py_ssize_t size = Py_TYPE(self)->tp_basicsize; + + if (self->buf.items != NULL) { + size += (Py_ssize_t)self->buf.items_cap * (Py_ssize_t)sizeof(PyObject *); + } + + return PyLong_FromSsize_t(size); +} /*[clinic input] @classmethod @@ -534,6 +546,7 @@ static PyMethodDef simplequeue_methods[] = { _QUEUE_SIMPLEQUEUE_PUT_METHODDEF _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF + {"__sizeof__", (PyCFunction)simplequeue_sizeof, METH_NOARGS, NULL}, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ From b2b05eab9f846abb1b20fefe1ad7763c00023167 Mon Sep 17 00:00:00 2001 From: Aniket Singh Yadav Date: Wed, 24 Dec 2025 20:04:55 +0530 Subject: [PATCH 02/10] implement __sizeof__ for SimpleQueue to account for ring-buffer storage --- Lib/test/test_queue.py | 9 +++++---- Modules/_queuemodule.c | 24 +++++++++++++++++------- Modules/clinic/_queuemodule.c.h | 32 +++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index d53787e98e35ea..3734817eafe5b7 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -9,7 +9,8 @@ from test.support import gc_collect, bigmemtest from test.support import import_helper from test.support import threading_helper -import ctypes +import sys +from test import support # queue module depends on threading primitives threading_helper.requires_working_threading(module=True) @@ -1034,12 +1035,12 @@ def test_is_default(self): def test_simplequeue_sizeof_reflects_buffer_growth(self): q = self.type2test() - before = q.__sizeof__() + before = sys.getsizeof(q) for _ in range(1000): q.put(object()) - after = q.__sizeof__() + after = sys.getsizeof(q) self.assertGreater(after, before) - ptr = ctypes.sizeof(ctypes.c_void_p) + ptr = support.calcobjsize(1) - support.calcobjsize(0) self.assertEqual((after - before) % ptr, 0) def test_reentrancy(self): diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 614f566649b144..7b17b7ad295b38 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -238,18 +238,28 @@ simplequeue_traverse(PyObject *op, visitproc visit, void *arg) Py_VISIT(Py_TYPE(self)); return 0; } -static PyObject * -simplequeue_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored)) + +/*[clinic input] +@critical_section +_queue.SimpleQueue.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self) { - simplequeueobject *self = simplequeueobject_CAST(op); Py_ssize_t size = Py_TYPE(self)->tp_basicsize; + PyObject **items = self->buf.items; + Py_ssize_t items_cap = self->buf.items_cap; - if (self->buf.items != NULL) { - size += (Py_ssize_t)self->buf.items_cap * (Py_ssize_t)sizeof(PyObject *); + if (items != NULL) { + size += items_cap * (Py_ssize_t)sizeof(void *); } - return PyLong_FromSsize_t(size); + return size; } +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/ /*[clinic input] @classmethod @@ -546,7 +556,7 @@ static PyMethodDef simplequeue_methods[] = { _QUEUE_SIMPLEQUEUE_PUT_METHODDEF _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF - {"__sizeof__", (PyCFunction)simplequeue_sizeof, METH_NOARGS, NULL}, + _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 1751d68716ba5f..97b5542241fb0c 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -9,6 +9,36 @@ preserve #include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_modsupport.h" // _PyArg_NoKeywords() +PyDoc_STRVAR(_queue_SimpleQueue___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_queue_SimpleQueue___sizeof__, METH_NOARGS, _queue_SimpleQueue___sizeof____doc__}, + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + _return_value = _queue_SimpleQueue___sizeof___impl((simplequeueobject *)self); + Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -358,4 +388,4 @@ _queue_SimpleQueue_qsize(PyObject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=1d3efe9df89997cf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e6a05dc21a1e9fca input=a9049054013a1b77]*/ From 205fd00ed473c664304ed75766fbb03cfab9e851 Mon Sep 17 00:00:00 2001 From: Aniket Singh Yadav Date: Wed, 24 Dec 2025 20:25:01 +0530 Subject: [PATCH 03/10] implement __sizeof__ for SimpleQueue to account for ring-buffer storage --- Lib/test/test_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 3734817eafe5b7..a67f5c51cc00a5 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1040,7 +1040,7 @@ def test_simplequeue_sizeof_reflects_buffer_growth(self): q.put(object()) after = sys.getsizeof(q) self.assertGreater(after, before) - ptr = support.calcobjsize(1) - support.calcobjsize(0) + ptr = support.calcobjsize("P") - support.calcobjsize("") self.assertEqual((after - before) % ptr, 0) def test_reentrancy(self): From 21014aa366aad3ef99360af00f28373765b040df Mon Sep 17 00:00:00 2001 From: Aniket Singh Yadav Date: Fri, 2 Jan 2026 14:37:30 +0530 Subject: [PATCH 04/10] implement __sizeof__ for SimpleQueue to account for ring-buffer storage --- Modules/_queuemodule.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 7b17b7ad295b38..8fee47ec8eb12e 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -248,19 +248,12 @@ Returns size in memory, in bytes. static Py_ssize_t _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/ { - Py_ssize_t size = Py_TYPE(self)->tp_basicsize; - PyObject **items = self->buf.items; - Py_ssize_t items_cap = self->buf.items_cap; - - if (items != NULL) { - size += items_cap * (Py_ssize_t)sizeof(void *); - } - - return size; + Py_ssize_t res = sizeof(simplequeueobject); + res += self->buf.items_cap * sizeof(PyObject *); + return res; } -/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/ - /*[clinic input] @classmethod _queue.SimpleQueue.__new__ as simplequeue_new From de68f62136567c6e4dbcae0355467e29dd6926ea Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 2 Jan 2026 09:32:44 +0000 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst diff --git a/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst new file mode 100644 index 00000000000000..f086e70746946a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst @@ -0,0 +1 @@ +Fix ``queue.SimpleQueue.__sizeof__()`` computation. From 654673aac1f06eed650ce78e1f4cfb24d3fe0057 Mon Sep 17 00:00:00 2001 From: Aniket <148300120+Aniketsy@users.noreply.github.com> Date: Sat, 3 Jan 2026 11:54:14 +0530 Subject: [PATCH 06/10] Update Lib/test/test_queue.py Co-authored-by: Sam Gross --- Lib/test/test_queue.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index a67f5c51cc00a5..00e6f11165e26d 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -1033,15 +1033,13 @@ def test_is_default(self): self.assertIs(self.type2test, self.queue.SimpleQueue) self.assertIs(self.type2test, self.queue.SimpleQueue) - def test_simplequeue_sizeof_reflects_buffer_growth(self): + def test_simplequeue_sizeof(self): q = self.type2test() - before = sys.getsizeof(q) + basesize = support.calcobjsize('?nnPnnP') + support.check_sizeof(self, q, basesize + struct.calcsize(8 * 'P')) for _ in range(1000): q.put(object()) - after = sys.getsizeof(q) - self.assertGreater(after, before) - ptr = support.calcobjsize("P") - support.calcobjsize("") - self.assertEqual((after - before) % ptr, 0) + support.check_sizeof(self, q, basesize + struct.calcsize(1024 * 'P')) def test_reentrancy(self): # bpo-14976: put() may be called reentrantly in an asynchronous From de5b4c7462f1a243063de440390891056c279795 Mon Sep 17 00:00:00 2001 From: Aniket <148300120+Aniketsy@users.noreply.github.com> Date: Sat, 3 Jan 2026 11:54:35 +0530 Subject: [PATCH 07/10] Update Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- .../next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst index f086e70746946a..c1d78067c03dfa 100644 --- a/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst +++ b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst @@ -1 +1 @@ -Fix ``queue.SimpleQueue.__sizeof__()`` computation. +:mod:`queue`: Fix :meth:`SimpleQueue.__sizeof__ ` computation. From 9e67b66e1fea392c2066417006c314f7109d122f Mon Sep 17 00:00:00 2001 From: Aniket <148300120+Aniketsy@users.noreply.github.com> Date: Sat, 3 Jan 2026 11:54:48 +0530 Subject: [PATCH 08/10] Update Modules/_queuemodule.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/_queuemodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 8fee47ec8eb12e..c4a9400ed2067c 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -254,6 +254,7 @@ _queue_SimpleQueue___sizeof___impl(simplequeueobject *self) res += self->buf.items_cap * sizeof(PyObject *); return res; } + /*[clinic input] @classmethod _queue.SimpleQueue.__new__ as simplequeue_new From 034a9cd083875962392ae9c7d1d5801022e38b04 Mon Sep 17 00:00:00 2001 From: Aniket Singh Yadav Date: Sat, 3 Jan 2026 12:30:24 +0530 Subject: [PATCH 09/10] implement __sizeof__ for SimpleQueue to account for ring-buffer storage --- Lib/test/test_queue.py | 2 +- Modules/_queuemodule.c | 32 ++++++++--------- Modules/clinic/_queuemodule.c.h | 62 ++++++++++++++++----------------- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 00e6f11165e26d..f2898de469e349 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -2,6 +2,7 @@ # to ensure the Queue locks remain stable. import itertools import random +import struct import threading import time import unittest @@ -9,7 +10,6 @@ from test.support import gc_collect, bigmemtest from test.support import import_helper from test.support import threading_helper -import sys from test import support # queue module depends on threading primitives diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index c4a9400ed2067c..a45959346bc1f2 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -239,22 +239,6 @@ simplequeue_traverse(PyObject *op, visitproc visit, void *arg) return 0; } -/*[clinic input] -@critical_section -_queue.SimpleQueue.__sizeof__ -> Py_ssize_t - -Returns size in memory, in bytes. -[clinic start generated code]*/ - -static Py_ssize_t -_queue_SimpleQueue___sizeof___impl(simplequeueobject *self) -/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/ -{ - Py_ssize_t res = sizeof(simplequeueobject); - res += self->buf.items_cap * sizeof(PyObject *); - return res; -} - /*[clinic input] @classmethod _queue.SimpleQueue.__new__ as simplequeue_new @@ -516,6 +500,22 @@ _queue_SimpleQueue_qsize_impl(simplequeueobject *self) return RingBuf_Len(&self->buf); } +/*[clinic input] +@critical_section +_queue.SimpleQueue.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self) +/*[clinic end generated code: output=58ce4e3bbc078fd4 input=a3a7f05c9616598f]*/ +{ + Py_ssize_t res = sizeof(simplequeueobject); + res += self->buf.items_cap * sizeof(PyObject *); + return res; +} + static int queue_traverse(PyObject *m, visitproc visit, void *arg) { diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 97b5542241fb0c..c9482f40acb9d4 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -9,36 +9,6 @@ preserve #include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_modsupport.h" // _PyArg_NoKeywords() -PyDoc_STRVAR(_queue_SimpleQueue___sizeof____doc__, -"__sizeof__($self, /)\n" -"--\n" -"\n" -"Returns size in memory, in bytes."); - -#define _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF \ - {"__sizeof__", (PyCFunction)_queue_SimpleQueue___sizeof__, METH_NOARGS, _queue_SimpleQueue___sizeof____doc__}, - -static Py_ssize_t -_queue_SimpleQueue___sizeof___impl(simplequeueobject *self); - -static PyObject * -_queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - Py_BEGIN_CRITICAL_SECTION(self); - _return_value = _queue_SimpleQueue___sizeof___impl((simplequeueobject *)self); - Py_END_CRITICAL_SECTION(); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -388,4 +358,34 @@ _queue_SimpleQueue_qsize(PyObject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=e6a05dc21a1e9fca input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_queue_SimpleQueue___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_queue_SimpleQueue___sizeof__, METH_NOARGS, _queue_SimpleQueue___sizeof____doc__}, + +static Py_ssize_t +_queue_SimpleQueue___sizeof___impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + _return_value = _queue_SimpleQueue___sizeof___impl((simplequeueobject *)self); + Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=4af5d1b1ea31ac7d input=a9049054013a1b77]*/ From 887af43330b3affaf4ee11204f9c77beef3550cf Mon Sep 17 00:00:00 2001 From: Aniket <148300120+Aniketsy@users.noreply.github.com> Date: Sun, 4 Jan 2026 09:49:38 +0530 Subject: [PATCH 10/10] Update Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- .../next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst index c1d78067c03dfa..cb5458f28af667 100644 --- a/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst +++ b/Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst @@ -1 +1 @@ -:mod:`queue`: Fix :meth:`SimpleQueue.__sizeof__ ` computation. +:mod:`queue`: Fix :meth:`!SimpleQueue.__sizeof__` computation.