mirror of https://github.com/python/cpython
Issue #25914: Fixed and simplified OrderedDict.__sizeof__.
This commit is contained in:
parent
5af856404a
commit
0ce7a3a34c
|
@ -98,7 +98,7 @@ PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
|
||||||
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
|
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
|
||||||
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
|
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
|
||||||
Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
|
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_Pop(PyDictObject *, PyObject *, PyObject *);
|
||||||
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
|
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
|
||||||
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
|
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import contextlib
|
||||||
import copy
|
import copy
|
||||||
import pickle
|
import pickle
|
||||||
from random import randrange, shuffle
|
from random import randrange, shuffle
|
||||||
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from collections.abc import MutableMapping
|
from collections.abc import MutableMapping
|
||||||
|
@ -596,6 +597,37 @@ class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
||||||
|
|
||||||
module = c_coll
|
module = c_coll
|
||||||
OrderedDict = c_coll.OrderedDict
|
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):
|
def test_key_change_during_iteration(self):
|
||||||
OrderedDict = self.OrderedDict
|
OrderedDict = self.OrderedDict
|
||||||
|
|
|
@ -28,6 +28,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #25914: Fixed and simplified OrderedDict.__sizeof__.
|
||||||
|
|
||||||
- Issue #25902: Fixed various refcount issues in ElementTree iteration.
|
- Issue #25902: Fixed various refcount issues in ElementTree iteration.
|
||||||
|
|
||||||
- Issue #25717: Restore the previous behaviour of tolerating most fstat()
|
- Issue #25717: Restore the previous behaviour of tolerating most fstat()
|
||||||
|
|
|
@ -2554,7 +2554,7 @@ dict_tp_clear(PyObject *op)
|
||||||
|
|
||||||
static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
|
static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
|
||||||
|
|
||||||
PyObject *
|
Py_ssize_t
|
||||||
_PyDict_SizeOf(PyDictObject *mp)
|
_PyDict_SizeOf(PyDictObject *mp)
|
||||||
{
|
{
|
||||||
Py_ssize_t size, res;
|
Py_ssize_t size, res;
|
||||||
|
@ -2567,7 +2567,7 @@ _PyDict_SizeOf(PyDictObject *mp)
|
||||||
in the type object. */
|
in the type object. */
|
||||||
if (mp->ma_keys->dk_refcnt == 1)
|
if (mp->ma_keys->dk_refcnt == 1)
|
||||||
res += sizeof(PyDictKeysObject) + (size-1) * sizeof(PyDictKeyEntry);
|
res += sizeof(PyDictKeysObject) + (size-1) * sizeof(PyDictKeyEntry);
|
||||||
return PyLong_FromSsize_t(res);
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
Py_ssize_t
|
||||||
|
@ -2576,6 +2576,12 @@ _PyDict_KeysSize(PyDictKeysObject *keys)
|
||||||
return sizeof(PyDictKeysObject) + (DK_SIZE(keys)-1) * sizeof(PyDictKeyEntry);
|
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(getitem__doc__, "x.__getitem__(y) <==> x[y]");
|
||||||
|
|
||||||
PyDoc_STRVAR(sizeof__doc__,
|
PyDoc_STRVAR(sizeof__doc__,
|
||||||
|
@ -2623,7 +2629,7 @@ static PyMethodDef mapp_methods[] = {
|
||||||
DICT___CONTAINS___METHODDEF
|
DICT___CONTAINS___METHODDEF
|
||||||
{"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST,
|
{"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST,
|
||||||
getitem__doc__},
|
getitem__doc__},
|
||||||
{"__sizeof__", (PyCFunction)_PyDict_SizeOf, METH_NOARGS,
|
{"__sizeof__", (PyCFunction)dict_sizeof, METH_NOARGS,
|
||||||
sizeof__doc__},
|
sizeof__doc__},
|
||||||
{"get", (PyCFunction)dict_get, METH_VARARGS,
|
{"get", (PyCFunction)dict_get, METH_VARARGS,
|
||||||
get__doc__},
|
get__doc__},
|
||||||
|
|
|
@ -940,27 +940,7 @@ PyDoc_STRVAR(odict_sizeof__doc__, "");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_sizeof(PyODictObject *od)
|
odict_sizeof(PyODictObject *od)
|
||||||
{
|
{
|
||||||
PyObject *pylong;
|
Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
|
||||||
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;
|
|
||||||
|
|
||||||
res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
|
res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
|
||||||
if (!_odict_EMPTY(od)) {
|
if (!_odict_EMPTY(od)) {
|
||||||
res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
|
res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
|
||||||
|
|
Loading…
Reference in New Issue