Issue 3048: Fixed sys.getsizeof for unicode objects.
This commit is contained in:
parent
0705bc0823
commit
901c997de0
|
@ -421,11 +421,14 @@ class SizeofTest(unittest.TestCase):
|
||||||
self.file.close()
|
self.file.close()
|
||||||
test.test_support.unlink(test.test_support.TESTFN)
|
test.test_support.unlink(test.test_support.TESTFN)
|
||||||
|
|
||||||
def check_sizeof(self, o, size):
|
def check_sizeof(self, o, size, size2=None):
|
||||||
|
"""Check size of o. Possible are size and optionally size2)."""
|
||||||
result = sys.getsizeof(o)
|
result = sys.getsizeof(o)
|
||||||
msg = 'wrong size for %s: got %d, expected %d' \
|
msg = 'wrong size for %s: got %d, expected ' % (type(o), result)
|
||||||
% (type(o), result, size)
|
if (size2 != None) and (result != size):
|
||||||
self.assertEqual(result, size, msg)
|
self.assertEqual(result, size2, msg + str(size2))
|
||||||
|
else:
|
||||||
|
self.assertEqual(result, size, msg + str(size))
|
||||||
|
|
||||||
def align(self, value):
|
def align(self, value):
|
||||||
mod = value % self.p
|
mod = value % self.p
|
||||||
|
@ -517,10 +520,10 @@ class SizeofTest(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
# type (PyTypeObject + PyNumberMethods + PyMappingMethods +
|
# type (PyTypeObject + PyNumberMethods + PyMappingMethods +
|
||||||
# PySequenceMethods + PyBufferProcs)
|
# PySequenceMethods + PyBufferProcs)
|
||||||
len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p
|
len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p +\
|
||||||
|
l + 11*p + self.align(4)
|
||||||
self.check_sizeof(class_newstyle,
|
self.check_sizeof(class_newstyle,
|
||||||
h + len_typeobject + 42*p + 10*p + 3*p + 6*p)
|
h + len_typeobject + 41*p + 10*p + 3*p + 6*p)
|
||||||
|
|
||||||
|
|
||||||
def test_specialtypes(self):
|
def test_specialtypes(self):
|
||||||
i = self.i
|
i = self.i
|
||||||
|
@ -534,6 +537,24 @@ class SizeofTest(unittest.TestCase):
|
||||||
# list
|
# list
|
||||||
self.check_sizeof([], h + l + p + l)
|
self.check_sizeof([], h + l + p + l)
|
||||||
self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
|
self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
|
||||||
|
# unicode
|
||||||
|
import math
|
||||||
|
usize = math.log(sys.maxunicode + 1, 2) / 8
|
||||||
|
samples = [u'', u'1'*100]
|
||||||
|
# we need to test for both sizes, because we don't know if the string
|
||||||
|
# has been cached
|
||||||
|
for s in samples:
|
||||||
|
basicsize = h + l + p + l + p + usize * (len(s) + 1)
|
||||||
|
self.check_sizeof(s, basicsize,\
|
||||||
|
size2=basicsize + sys.getsizeof(str(s)))
|
||||||
|
# XXX trigger caching encoded version as Python string
|
||||||
|
s = samples[1]
|
||||||
|
try:
|
||||||
|
getattr(sys, s)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
self.check_sizeof(s, basicsize + sys.getsizeof(str(s)))
|
||||||
|
|
||||||
h += l
|
h += l
|
||||||
# long
|
# long
|
||||||
|
|
|
@ -7895,6 +7895,29 @@ PyDoc_STRVAR(p_format__doc__,
|
||||||
\n\
|
\n\
|
||||||
");
|
");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
unicode__sizeof__(PyUnicodeObject *v)
|
||||||
|
{
|
||||||
|
PyObject *res = NULL, *defsize = NULL;
|
||||||
|
|
||||||
|
res = PyInt_FromSsize_t(sizeof(PyUnicodeObject) +
|
||||||
|
sizeof(Py_UNICODE) * (v->length + 1));
|
||||||
|
if (v->defenc) {
|
||||||
|
defsize = PyObject_CallMethod(v->defenc, "__sizeof__", NULL);
|
||||||
|
if (defsize == NULL) {
|
||||||
|
Py_DECREF(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
res = PyNumber_Add(res, defsize);
|
||||||
|
Py_DECREF(defsize);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(sizeof__doc__,
|
||||||
|
"S.__sizeof__() -> size of S in memory, in bytes\n\
|
||||||
|
\n\
|
||||||
|
");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicode_getnewargs(PyUnicodeObject *v)
|
unicode_getnewargs(PyUnicodeObject *v)
|
||||||
|
@ -7952,6 +7975,7 @@ static PyMethodDef unicode_methods[] = {
|
||||||
{"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
|
{"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
|
||||||
{"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
|
{"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
|
||||||
{"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
|
{"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
|
||||||
|
{"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
|
||||||
#if 0
|
#if 0
|
||||||
{"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
|
{"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue