diff options
-rw-r--r-- | Include/dictobject.h | 2 | ||||
-rw-r--r-- | Lib/test/test_ordered_dict.py | 32 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Objects/dictobject.c | 12 | ||||
-rw-r--r-- | Objects/odictobject.c | 22 |
5 files changed, 45 insertions, 25 deletions
diff --git a/Include/dictobject.h b/Include/dictobject.h index 80bd330..ba90aaf 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -98,7 +98,7 @@ PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); -PyObject *_PyDict_SizeOf(PyDictObject *); +Py_ssize_t _PyDict_SizeOf(PyDictObject *); PyObject *_PyDict_Pop(PyDictObject *, PyObject *, PyObject *); PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index e64c7e5..9f9922c 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -2,6 +2,7 @@ import contextlib import copy import pickle from random import randrange, shuffle +import struct import sys import unittest from collections.abc import MutableMapping @@ -604,6 +605,37 @@ class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): module = c_coll OrderedDict = c_coll.OrderedDict + check_sizeof = support.check_sizeof + + @support.cpython_only + def test_sizeof_exact(self): + OrderedDict = self.OrderedDict + calcsize = struct.calcsize + size = support.calcobjsize + check = self.check_sizeof + + basicsize = size('n2P' + '3PnPn2P') + calcsize('2nPn') + entrysize = calcsize('n2P') + calcsize('P') + nodesize = calcsize('Pn2P') + + od = OrderedDict() + check(od, basicsize + 8*entrysize) + od.x = 1 + check(od, basicsize + 8*entrysize) + od.update([(i, i) for i in range(3)]) + check(od, basicsize + 8*entrysize + 3*nodesize) + od.update([(i, i) for i in range(3, 10)]) + check(od, basicsize + 16*entrysize + 10*nodesize) + + check(od.keys(), size('P')) + check(od.items(), size('P')) + check(od.values(), size('P')) + + itersize = size('iP2n2P') + check(iter(od), itersize) + check(iter(od.keys()), itersize) + check(iter(od.items()), itersize) + check(iter(od.values()), itersize) def test_key_change_during_iteration(self): OrderedDict = self.OrderedDict @@ -115,6 +115,8 @@ Core and Builtins Library ------- +- Issue #25914: Fixed and simplified OrderedDict.__sizeof__. + - Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster. - Issue #25873: Optimized iterating ElementTree. Iterating elements diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 752853f..6f57db0 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2557,7 +2557,7 @@ dict_tp_clear(PyObject *op) static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); -PyObject * +Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { Py_ssize_t size, res; @@ -2570,7 +2570,7 @@ _PyDict_SizeOf(PyDictObject *mp) in the type object. */ if (mp->ma_keys->dk_refcnt == 1) res += sizeof(PyDictKeysObject) + (size-1) * sizeof(PyDictKeyEntry); - return PyLong_FromSsize_t(res); + return res; } Py_ssize_t @@ -2579,6 +2579,12 @@ _PyDict_KeysSize(PyDictKeysObject *keys) return sizeof(PyDictKeysObject) + (DK_SIZE(keys)-1) * sizeof(PyDictKeyEntry); } +PyObject * +dict_sizeof(PyDictObject *mp) +{ + return PyLong_FromSsize_t(_PyDict_SizeOf(mp)); +} + PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); PyDoc_STRVAR(sizeof__doc__, @@ -2626,7 +2632,7 @@ static PyMethodDef mapp_methods[] = { DICT___CONTAINS___METHODDEF {"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST, getitem__doc__}, - {"__sizeof__", (PyCFunction)_PyDict_SizeOf, METH_NOARGS, + {"__sizeof__", (PyCFunction)dict_sizeof, METH_NOARGS, sizeof__doc__}, {"get", (PyCFunction)dict_get, METH_VARARGS, get__doc__}, diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 4e51f4d..c15b408 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -940,27 +940,7 @@ PyDoc_STRVAR(odict_sizeof__doc__, ""); static PyObject * odict_sizeof(PyODictObject *od) { - PyObject *pylong; - Py_ssize_t res, temp; - - pylong = _PyDict_SizeOf((PyDictObject *)od); - if (pylong == NULL) - return NULL; - res = PyLong_AsSsize_t(pylong); - Py_DECREF(pylong); - if (res == -1 && PyErr_Occurred()) - return NULL; - - /* instance dict */ - pylong = _PyDict_SizeOf((PyDictObject *)od->od_inst_dict); - if (pylong == NULL) - return NULL; - temp = PyLong_AsSsize_t(pylong); - Py_DECREF(pylong); - if (temp == -1 && PyErr_Occurred()) - return NULL; - res += temp; - + Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od); res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */ if (!_odict_EMPTY(od)) { res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */ |