Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2dae92a

Browse files
Issue #15475: Add __sizeof__ implementations for itertools objects.
1 parent a881a7f commit 2dae92a

3 files changed

Lines changed: 95 additions & 1 deletion

File tree

Lib/test/test_itertools.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import copy
1111
import pickle
1212
from functools import reduce
13+
import sys
14+
import struct
1315
maxsize = support.MAX_Py_ssize_t
1416
minsize = -maxsize-1
1517

@@ -1807,6 +1809,44 @@ def __init__(self, newarg=None, *args):
18071809
# we expect type errors because of wrong argument count
18081810
self.assertNotIn("does not take keyword arguments", err.args[0])
18091811

1812+
@support.cpython_only
1813+
class SizeofTest(unittest.TestCase):
1814+
def setUp(self):
1815+
self.ssize_t = struct.calcsize('n')
1816+
1817+
check_sizeof = support.check_sizeof
1818+
1819+
def test_product_sizeof(self):
1820+
basesize = support.calcobjsize('3Pi')
1821+
check = self.check_sizeof
1822+
check(product('ab', '12'), basesize + 2 * self.ssize_t)
1823+
check(product(*(('abc',) * 10)), basesize + 10 * self.ssize_t)
1824+
1825+
def test_combinations_sizeof(self):
1826+
basesize = support.calcobjsize('3Pni')
1827+
check = self.check_sizeof
1828+
check(combinations('abcd', 3), basesize + 3 * self.ssize_t)
1829+
check(combinations(range(10), 4), basesize + 4 * self.ssize_t)
1830+
1831+
def test_combinations_with_replacement_sizeof(self):
1832+
cwr = combinations_with_replacement
1833+
basesize = support.calcobjsize('3Pni')
1834+
check = self.check_sizeof
1835+
check(cwr('abcd', 3), basesize + 3 * self.ssize_t)
1836+
check(cwr(range(10), 4), basesize + 4 * self.ssize_t)
1837+
1838+
def test_permutations_sizeof(self):
1839+
basesize = support.calcobjsize('4Pni')
1840+
check = self.check_sizeof
1841+
check(permutations('abcd'),
1842+
basesize + 4 * self.ssize_t + 4 * self.ssize_t)
1843+
check(permutations('abcd', 3),
1844+
basesize + 4 * self.ssize_t + 3 * self.ssize_t)
1845+
check(permutations('abcde', 3),
1846+
basesize + 5 * self.ssize_t + 3 * self.ssize_t)
1847+
check(permutations(range(10), 4),
1848+
basesize + 10 * self.ssize_t + 4 * self.ssize_t)
1849+
18101850

18111851
libreftest = """ Doctest for examples in the library reference: libitertools.tex
18121852
@@ -2042,7 +2082,8 @@ def __init__(self, newarg=None, *args):
20422082
def test_main(verbose=None):
20432083
test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
20442084
RegressionTests, LengthTransparency,
2045-
SubclassWithKwargsTest, TestExamples)
2085+
SubclassWithKwargsTest, TestExamples,
2086+
SizeofTest)
20462087
support.run_unittest(*test_classes)
20472088

20482089
# verify reference counting

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Core and Builtins
2121
Library
2222
-------
2323

24+
- Issue #15475: Add __sizeof__ implementations for itertools objects.
25+
2426
- Issue #19880: Fix a reference leak in unittest.TestCase. Explicitly break
2527
reference cycles between frames and the _Outcome instance.
2628

Modules/itertoolsmodule.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,18 @@ product_dealloc(productobject *lz)
20572057
Py_TYPE(lz)->tp_free(lz);
20582058
}
20592059

2060+
static PyObject *
2061+
product_sizeof(productobject *lz, void *unused)
2062+
{
2063+
Py_ssize_t res;
2064+
2065+
res = sizeof(productobject);
2066+
res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
2067+
return PyLong_FromSsize_t(res);
2068+
}
2069+
2070+
PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
2071+
20602072
static int
20612073
product_traverse(productobject *lz, visitproc visit, void *arg)
20622074
{
@@ -2226,6 +2238,8 @@ static PyMethodDef product_methods[] = {
22262238
reduce_doc},
22272239
{"__setstate__", (PyCFunction)product_setstate, METH_O,
22282240
setstate_doc},
2241+
{"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS,
2242+
sizeof_doc},
22292243
{NULL, NULL} /* sentinel */
22302244
};
22312245

@@ -2366,6 +2380,16 @@ combinations_dealloc(combinationsobject *co)
23662380
Py_TYPE(co)->tp_free(co);
23672381
}
23682382

2383+
static PyObject *
2384+
combinations_sizeof(combinationsobject *co, void *unused)
2385+
{
2386+
Py_ssize_t res;
2387+
2388+
res = sizeof(combinationsobject);
2389+
res += co->r * sizeof(Py_ssize_t);
2390+
return PyLong_FromSsize_t(res);
2391+
}
2392+
23692393
static int
23702394
combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
23712395
{
@@ -2537,6 +2561,8 @@ static PyMethodDef combinations_methods[] = {
25372561
reduce_doc},
25382562
{"__setstate__", (PyCFunction)combinations_setstate, METH_O,
25392563
setstate_doc},
2564+
{"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS,
2565+
sizeof_doc},
25402566
{NULL, NULL} /* sentinel */
25412567
};
25422568

@@ -2695,6 +2721,16 @@ cwr_dealloc(cwrobject *co)
26952721
Py_TYPE(co)->tp_free(co);
26962722
}
26972723

2724+
static PyObject *
2725+
cwr_sizeof(cwrobject *co, void *unused)
2726+
{
2727+
Py_ssize_t res;
2728+
2729+
res = sizeof(cwrobject);
2730+
res += co->r * sizeof(Py_ssize_t);
2731+
return PyLong_FromSsize_t(res);
2732+
}
2733+
26982734
static int
26992735
cwr_traverse(cwrobject *co, visitproc visit, void *arg)
27002736
{
@@ -2854,6 +2890,8 @@ static PyMethodDef cwr_methods[] = {
28542890
reduce_doc},
28552891
{"__setstate__", (PyCFunction)cwr_setstate, METH_O,
28562892
setstate_doc},
2893+
{"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS,
2894+
sizeof_doc},
28572895
{NULL, NULL} /* sentinel */
28582896
};
28592897

@@ -3030,6 +3068,17 @@ permutations_dealloc(permutationsobject *po)
30303068
Py_TYPE(po)->tp_free(po);
30313069
}
30323070

3071+
static PyObject *
3072+
permutations_sizeof(permutationsobject *po, void *unused)
3073+
{
3074+
Py_ssize_t res;
3075+
3076+
res = sizeof(permutationsobject);
3077+
res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
3078+
res += po->r * sizeof(Py_ssize_t);
3079+
return PyLong_FromSsize_t(res);
3080+
}
3081+
30333082
static int
30343083
permutations_traverse(permutationsobject *po, visitproc visit, void *arg)
30353084
{
@@ -3235,6 +3284,8 @@ static PyMethodDef permuations_methods[] = {
32353284
reduce_doc},
32363285
{"__setstate__", (PyCFunction)permutations_setstate, METH_O,
32373286
setstate_doc},
3287+
{"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS,
3288+
sizeof_doc},
32383289
{NULL, NULL} /* sentinel */
32393290
};
32403291

0 commit comments

Comments
 (0)