changeset: 99633:be3998aed1e7 branch: 2.7 parent: 99626:11c789c034fe user: Serhiy Storchaka date: Sat Dec 19 20:07:48 2015 +0200 files: Lib/test/test_sys.py Misc/NEWS Modules/_collectionsmodule.c Modules/_io/bufferedio.c Modules/_io/bytesio.c Modules/_struct.c Modules/arraymodule.c Modules/mmapmodule.c Modules/parsermodule.c Objects/bytearrayobject.c Objects/dictobject.c Objects/listobject.c Objects/setobject.c description: 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. diff -r 11c789c034fe -r be3998aed1e7 Lib/test/test_sys.py --- a/Lib/test/test_sys.py Fri Dec 18 15:46:52 2015 -0500 +++ b/Lib/test/test_sys.py Sat Dec 19 20:07:48 2015 +0200 @@ -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 cStringIO +import gc +import operator +import os import struct -import operator +import sys class SysModuleTest(unittest.TestCase): @@ -754,6 +757,32 @@ 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 diff -r 11c789c034fe -r be3998aed1e7 Misc/NEWS --- a/Misc/NEWS Fri Dec 18 15:46:52 2015 -0500 +++ b/Misc/NEWS Sat Dec 19 20:07:48 2015 +0200 @@ -10,6 +10,10 @@ 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 -r 11c789c034fe -r be3998aed1e7 Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/_collectionsmodule.c Sat Dec 19 20:07:48 2015 +0200 @@ -1103,7 +1103,7 @@ 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 -r 11c789c034fe -r be3998aed1e7 Modules/_io/bufferedio.c --- a/Modules/_io/bufferedio.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/_io/bufferedio.c Sat Dec 19 20:07:48 2015 +0200 @@ -391,7 +391,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Modules/_io/bytesio.c --- a/Modules/_io/bytesio.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/_io/bytesio.c Sat Dec 19 20:07:48 2015 +0200 @@ -809,7 +809,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Modules/_struct.c --- a/Modules/_struct.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/_struct.c Sat Dec 19 20:07:48 2015 +0200 @@ -1737,7 +1737,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Modules/arraymodule.c --- a/Modules/arraymodule.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/arraymodule.c Sat Dec 19 20:07:48 2015 +0200 @@ -1541,7 +1541,7 @@ 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 -r 11c789c034fe -r be3998aed1e7 Modules/mmapmodule.c --- a/Modules/mmapmodule.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/mmapmodule.c Sat Dec 19 20:07:48 2015 +0200 @@ -655,7 +655,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Modules/parsermodule.c --- a/Modules/parsermodule.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Modules/parsermodule.c Sat Dec 19 20:07:48 2015 +0200 @@ -720,7 +720,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Objects/bytearrayobject.c Sat Dec 19 20:07:48 2015 +0200 @@ -2780,7 +2780,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Objects/dictobject.c --- a/Objects/dictobject.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Objects/dictobject.c Sat Dec 19 20:07:48 2015 +0200 @@ -2152,7 +2152,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Objects/listobject.c --- a/Objects/listobject.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Objects/listobject.c Sat Dec 19 20:07:48 2015 +0200 @@ -2469,7 +2469,7 @@ { 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 -r 11c789c034fe -r be3998aed1e7 Objects/setobject.c --- a/Objects/setobject.c Fri Dec 18 15:46:52 2015 -0500 +++ b/Objects/setobject.c Sat Dec 19 20:07:48 2015 +0200 @@ -1985,7 +1985,7 @@ { 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);