Skip to content

Commit 4d03baf

Browse files
committed
implement __sizeof__ for SimpleQueue to account for ring-buffer storage
1 parent 50ecd6b commit 4d03baf

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

Lib/test/test_queue.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from test.support import gc_collect, bigmemtest
1010
from test.support import import_helper
1111
from test.support import threading_helper
12+
import ctypes
1213

1314
# queue module depends on threading primitives
1415
threading_helper.requires_working_threading(module=True)
@@ -1031,6 +1032,16 @@ def test_is_default(self):
10311032
self.assertIs(self.type2test, self.queue.SimpleQueue)
10321033
self.assertIs(self.type2test, self.queue.SimpleQueue)
10331034

1035+
def test_simplequeue_sizeof_reflects_buffer_growth(self):
1036+
q = self.type2test()
1037+
before = q.__sizeof__()
1038+
for _ in range(1000):
1039+
q.put(object())
1040+
after = q.__sizeof__()
1041+
self.assertGreater(after, before)
1042+
ptr = ctypes.sizeof(ctypes.c_void_p)
1043+
self.assertEqual((after - before) % ptr, 0)
1044+
10341045
def test_reentrancy(self):
10351046
# bpo-14976: put() may be called reentrantly in an asynchronous
10361047
# callback.

Modules/_queuemodule.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,18 @@ simplequeue_traverse(PyObject *op, visitproc visit, void *arg)
238238
Py_VISIT(Py_TYPE(self));
239239
return 0;
240240
}
241+
static PyObject *
242+
simplequeue_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored))
243+
{
244+
simplequeueobject *self = simplequeueobject_CAST(op);
245+
Py_ssize_t size = Py_TYPE(self)->tp_basicsize;
246+
247+
if (self->buf.items != NULL) {
248+
size += (Py_ssize_t)self->buf.items_cap * (Py_ssize_t)sizeof(PyObject *);
249+
}
250+
251+
return PyLong_FromSsize_t(size);
252+
}
241253

242254
/*[clinic input]
243255
@classmethod
@@ -534,6 +546,7 @@ static PyMethodDef simplequeue_methods[] = {
534546
_QUEUE_SIMPLEQUEUE_PUT_METHODDEF
535547
_QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF
536548
_QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF
549+
{"__sizeof__", (PyCFunction)simplequeue_sizeof, METH_NOARGS, NULL},
537550
{"__class_getitem__", Py_GenericAlias,
538551
METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
539552
{NULL, NULL} /* sentinel */

0 commit comments

Comments
 (0)