From 87c5b94c3980aa6f234b962acf047a3a5524986a Mon Sep 17 00:00:00 2001 From: Meador Inge Date: Mon, 23 Jul 2012 09:27:00 -0500 Subject: [PATCH] Issue #15402: Add a __sizeof__ method to struct.Struct. Initial patch by Serhiy Storchaka. --- Lib/test/test_struct.py | 10 ++++++++++ Misc/NEWS | 4 ++++ Modules/_struct.c | 17 +++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 5a63135a1a..caada9cadb 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -544,6 +544,16 @@ class StructTest(unittest.TestCase): hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) self.assertRaises(struct.error, struct.calcsize, hugecount2) + def test_sizeof(self): + self.assertGreater(sys.getsizeof(struct.Struct('BHILfdspP')), + sys.getsizeof(struct.Struct('B'))) + self.assertGreaterEqual(sys.getsizeof(struct.Struct('123B')), + sys.getsizeof(struct.Struct('B'))) + self.assertGreaterEqual(sys.getsizeof(struct.Struct('B' * 123)), + sys.getsizeof(struct.Struct('123B'))) + self.assertGreaterEqual(sys.getsizeof(struct.Struct('123xB')), + sys.getsizeof(struct.Struct('B'))) + def test_main(): run_unittest(StructTest) diff --git a/Misc/NEWS b/Misc/NEWS index a279941eb3..ca0740ed91 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -90,6 +90,10 @@ Core and Builtins Library ------- +- Issue #15402: An issue in the struct module that caused sys.getsizeof to + return incorrect results for struct.Struct instances has been fixed. + Initial patch by Serhiy Storchaka. + - Issue #15232: when mangle_from is True, email.Generator now correctly mangles lines that start with 'From' that occur in a MIME preamble or epilog. diff --git a/Modules/_struct.c b/Modules/_struct.c index c158ebab92..3ede1d0188 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1693,6 +1693,22 @@ s_get_size(PyStructObject *self, void *unused) return PyInt_FromSsize_t(self->s_size); } +PyDoc_STRVAR(s_sizeof__doc__, +"S.__sizeof__() -> size of S in memory, in bytes"); + +static PyObject * +s_sizeof(PyStructObject *self) +{ + Py_ssize_t size; + formatcode *code; + + size = sizeof(PyStructObject) + sizeof(formatcode); + for (code = self->s_codes; code->fmtdef != NULL; code++) { + size += sizeof(formatcode); + } + return PyLong_FromSsize_t(size); +} + /* List of functions */ static struct PyMethodDef s_methods[] = { @@ -1701,6 +1717,7 @@ static struct PyMethodDef s_methods[] = { {"unpack", s_unpack, METH_O, s_unpack__doc__}, {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS, s_unpack_from__doc__}, + {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, {NULL, NULL} /* sentinel */ }; -- 2.40.0