diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-19 18:07:48 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-19 18:07:48 (GMT) |
commit | c06a6d0958e2eb4449605069b9c10d656ab756e8 (patch) | |
tree | 3be097cf344ed6c277ca77bd37f253f5c66d3a7d | |
parent | 6f3d5da36cb6f7a7472c69f92de16682e5a82620 (diff) | |
download | cpython-c06a6d0958e2eb4449605069b9c10d656ab756e8.zip cpython-c06a6d0958e2eb4449605069b9c10d656ab756e8.tar.gz cpython-c06a6d0958e2eb4449605069b9c10d656ab756e8.tar.bz2 |
Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size.
This allows sys.getsize() to work correctly with their subclasses with
__slots__ defined.
-rw-r--r-- | Lib/test/test_sys.py | 33 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/_collectionsmodule.c | 2 | ||||
-rw-r--r-- | Modules/_io/bufferedio.c | 2 | ||||
-rw-r--r-- | Modules/_io/bytesio.c | 2 | ||||
-rw-r--r-- | Modules/_struct.c | 2 | ||||
-rw-r--r-- | Modules/arraymodule.c | 2 | ||||
-rw-r--r-- | Modules/mmapmodule.c | 2 | ||||
-rw-r--r-- | Modules/parsermodule.c | 2 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 2 | ||||
-rw-r--r-- | Objects/dictobject.c | 2 | ||||
-rw-r--r-- | Objects/listobject.c | 2 | ||||
-rw-r--r-- | Objects/setobject.c | 2 |
13 files changed, 46 insertions, 13 deletions
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index de13f22..e6c17a2 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1,9 +1,12 @@ # -*- coding: iso-8859-1 -*- import unittest, test.test_support from test.script_helper import assert_python_ok, assert_python_failure -import sys, os, cStringIO -import struct +import cStringIO +import gc import operator +import os +import struct +import sys class SysModuleTest(unittest.TestCase): @@ -754,6 +757,32 @@ class SizeofTest(unittest.TestCase): check(xrange(1), size('3l')) check(xrange(66000), size('3l')) + def check_slots(self, obj, base, extra): + expected = sys.getsizeof(base) + struct.calcsize(extra) + if gc.is_tracked(obj) and not gc.is_tracked(base): + expected += struct.calcsize('3P') # PyGC_Head + self.assertEqual(sys.getsizeof(obj), expected) + + def test_slots(self): + # check all subclassable types defined in Objects/ that allow + # non-empty __slots__ + check = self.check_slots + class BA(bytearray): + __slots__ = 'a', 'b', 'c' + check(BA(), bytearray(), '3P') + class D(dict): + __slots__ = 'a', 'b', 'c' + check(D(x=[]), {'x': []}, '3P') + class L(list): + __slots__ = 'a', 'b', 'c' + check(L(), [], '3P') + class S(set): + __slots__ = 'a', 'b', 'c' + check(S(), set(), '3P') + class FS(frozenset): + __slots__ = 'a', 'b', 'c' + check(FS(), frozenset(), '3P') + def test_pythontypes(self): # check all types defined in Python/ size = test.test_support.calcobjsize @@ -10,6 +10,10 @@ What's New in Python 2.7.12? Core and Builtins ----------------- +- Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size. + This allows sys.getsize() to work correctly with their subclasses with + __slots__ defined. + - Issue #19543: Added Py3k warning for decoding unicode. - Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index aaac660..d4cc960 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1103,7 +1103,7 @@ deque_sizeof(dequeobject *deque, void *unused) Py_ssize_t res; Py_ssize_t blocks; - res = sizeof(dequeobject); + res = _PyObject_SIZE(Py_TYPE(deque)); blocks = (deque->leftindex + deque->len + BLOCKLEN - 1) / BLOCKLEN; assert(deque->leftindex + deque->len - 1 == (blocks - 1) * BLOCKLEN + deque->rightindex); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index b4632ed..dd518d7 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -391,7 +391,7 @@ buffered_sizeof(buffered *self, void *unused) { Py_ssize_t res; - res = sizeof(buffered); + res = _PyObject_SIZE(Py_TYPE(self)); if (self->buffer) res += self->buffer_size; return PyLong_FromSsize_t(res); diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index f643e91..82f3851 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -809,7 +809,7 @@ bytesio_sizeof(bytesio *self, void *unused) { Py_ssize_t res; - res = sizeof(bytesio); + res = _PyObject_SIZE(Py_TYPE(self)); if (self->buf) res += self->buf_size; return PyLong_FromSsize_t(res); diff --git a/Modules/_struct.c b/Modules/_struct.c index bca7a2e..02dd7d3 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1737,7 +1737,7 @@ s_sizeof(PyStructObject *self, void *unused) { Py_ssize_t size; - size = sizeof(PyStructObject) + sizeof(formatcode) * (self->s_len + 1); + size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode) * (self->s_len + 1); return PyLong_FromSsize_t(size); } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 1d1f0d3..f147115 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1541,7 +1541,7 @@ static PyObject * array_sizeof(arrayobject *self, PyObject *unused) { Py_ssize_t res; - res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize; + res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; return PyLong_FromSsize_t(res); } diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 8fdf7f7..1ebccdf 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -655,7 +655,7 @@ mmap__sizeof__method(mmap_object *self, void *unused) { Py_ssize_t res; - res = sizeof(mmap_object); + res = _PyObject_SIZE(Py_TYPE(self)); if (self->tagname) res += strlen(self->tagname) + 1; return PyLong_FromSsize_t(res); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index eb2d600..2434c67 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -720,7 +720,7 @@ parser_sizeof(PyST_Object *st, void *unused) { Py_ssize_t res; - res = sizeof(PyST_Object) + _PyNode_SizeOf(st->st_node); + res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node); return PyLong_FromSsize_t(res); } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 5276da5..1fdd916 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2780,7 +2780,7 @@ bytearray_sizeof(PyByteArrayObject *self) { Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char); return PyInt_FromSsize_t(res); } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 50afa3f..b281948 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2152,7 +2152,7 @@ dict_sizeof(PyDictObject *mp) { Py_ssize_t res; - res = sizeof(PyDictObject); + res = _PyObject_SIZE(Py_TYPE(mp)); if (mp->ma_table != mp->ma_smalltable) res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry); return PyInt_FromSsize_t(res); diff --git a/Objects/listobject.c b/Objects/listobject.c index 1f43ba2..27365b6 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2469,7 +2469,7 @@ list_sizeof(PyListObject *self) { Py_ssize_t res; - res = sizeof(PyListObject) + self->allocated * sizeof(void*); + res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*); return PyInt_FromSsize_t(res); } diff --git a/Objects/setobject.c b/Objects/setobject.c index 8a58d65..a9ebbec 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1985,7 +1985,7 @@ set_sizeof(PySetObject *so) { Py_ssize_t res; - res = sizeof(PySetObject); + res = _PyObject_SIZE(Py_TYPE(so)); if (so->table != so->smalltable) res = res + (so->mask + 1) * sizeof(setentry); return PyInt_FromSsize_t(res); |