]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140025: Fix `queue.SimpleQueue.__sizeof__()` to return correct size (#143137)
authorAniket <148300120+Aniketsy@users.noreply.github.com>
Thu, 8 Jan 2026 12:40:25 +0000 (18:10 +0530)
committerGitHub <noreply@github.com>
Thu, 8 Jan 2026 12:40:25 +0000 (12:40 +0000)
Lib/test/test_queue.py
Misc/NEWS.d/next/Library/2026-01-02-09-32-43.gh-issue-140025.zOX58_.rst [new file with mode: 0644]
Modules/_queuemodule.c
Modules/clinic/_queuemodule.c.h

index c855fb8fe2b05ae42745c8d67ceaf79e9a871307..f2898de469e349b03f316b78dc66ac70094e44e9 100644 (file)
@@ -2,6 +2,7 @@
 # to ensure the Queue locks remain stable.
 import itertools
 import random
+import struct
 import threading
 import time
 import unittest
@@ -9,6 +10,7 @@ import weakref
 from test.support import gc_collect, bigmemtest
 from test.support import import_helper
 from test.support import threading_helper
+from test import support
 
 # queue module depends on threading primitives
 threading_helper.requires_working_threading(module=True)
@@ -1031,6 +1033,14 @@ class CSimpleQueueTest(BaseSimpleQueueTest, unittest.TestCase):
         self.assertIs(self.type2test, self.queue.SimpleQueue)
         self.assertIs(self.type2test, self.queue.SimpleQueue)
 
+    def test_simplequeue_sizeof(self):
+        q = self.type2test()
+        basesize = support.calcobjsize('?nnPnnP')
+        support.check_sizeof(self, q, basesize + struct.calcsize(8 * 'P'))
+        for _ in range(1000):
+            q.put(object())
+        support.check_sizeof(self, q, basesize + struct.calcsize(1024 * 'P'))
+
     def test_reentrancy(self):
         # bpo-14976: put() may be called reentrantly in an asynchronous
         # callback.
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 (file)
index 0000000..cb5458f
--- /dev/null
@@ -0,0 +1 @@
+:mod:`queue`: Fix :meth:`!SimpleQueue.__sizeof__` computation.
index 01235c77bd7db8ea61e3434e20b506c7ce0ae488..a45959346bc1f20c0459826f578c3c26efda9289 100644 (file)
@@ -500,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)
 {
@@ -534,6 +550,7 @@ static PyMethodDef simplequeue_methods[] = {
     _QUEUE_SIMPLEQUEUE_PUT_METHODDEF
     _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF
     _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF
+    _QUEUE_SIMPLEQUEUE___SIZEOF___METHODDEF
     {"__class_getitem__",    Py_GenericAlias,
     METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
     {NULL,           NULL}              /* sentinel */
index 1751d68716ba5fa75c0f5390c92daeedf11edb84..c9482f40acb9d4cea4f4e394413908d5eafcfb7c 100644 (file)
@@ -358,4 +358,34 @@ _queue_SimpleQueue_qsize(PyObject *self, PyObject *Py_UNUSED(ignored))
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=1d3efe9df89997cf 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]*/