Skip to content

Commit 9b63d77

Browse files
committed
initial implementation and tests
1 parent 42351c3 commit 9b63d77

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

Lib/test/test_itertools.py

+10
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,16 @@ def test_compress(self):
506506
self.assertRaises(TypeError, compress, range(6)) # too few args
507507
self.assertRaises(TypeError, compress, range(6), None) # too many args
508508

509+
def test_ilen(self):
510+
self.assertEqual(ilen(range(10)), 10)
511+
it = iter(range(100))
512+
self.assertEqual(ilen(it), 100)
513+
self.assertEqual(ilen(it), 0)
514+
self.assertEqual(ilen('abcdefghij'), 10)
515+
self.assertEqual(ilen(range(100000)), 100000)
516+
self.assertRaises(TypeError, ilen) # too few args
517+
self.assertRaises(TypeError, ilen, 1) # not iterable
518+
509519
def test_count(self):
510520
self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
511521
self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])

Modules/clinic/itertoolsmodule.c.h

+10-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/itertoolsmodule.c

+70
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,75 @@ static PyType_Spec ziplongest_spec = {
38023802
};
38033803

38043804

3805+
/* ilen function *************************************************************/
3806+
3807+
/*[clinic input]
3808+
itertools.ilen
3809+
3810+
iterable: object
3811+
/
3812+
3813+
Equivalent to len(list(iterable)).
3814+
[clinic start generated code]*/
3815+
3816+
static PyObject *
3817+
itertools_ilen(PyObject *module, PyObject *iterable)
3818+
/*[clinic end generated code: output=99a1c852a6d09dd4 input=cf51dec933b693da]*/
3819+
{
3820+
PyObject *it, *item;
3821+
PyObject *(*iternext)(PyObject *);
3822+
PyObject *long_cnt = NULL;
3823+
PyObject *new_long_cnt, *temp;
3824+
Py_ssize_t cnt;
3825+
3826+
it = PyObject_GetIter(iterable);
3827+
if (it == NULL) {
3828+
return NULL;
3829+
}
3830+
3831+
cnt = 0;
3832+
iternext = *Py_TYPE(it)->tp_iternext;
3833+
while ((item = iternext(it)) != NULL) {
3834+
Py_DECREF(item);
3835+
cnt++;
3836+
if (cnt == PY_SSIZE_T_MAX) {
3837+
if (long_cnt == NULL) {
3838+
long_cnt = PyLong_FromSsize_t(cnt);
3839+
}
3840+
else {
3841+
new_long_cnt = PyLong_FromSsize_t(cnt);
3842+
temp = PyNumber_Add(long_cnt, new_long_cnt);
3843+
Py_SETREF(long_cnt, temp);
3844+
Py_DECREF(new_long_cnt);
3845+
}
3846+
cnt = 0;
3847+
}
3848+
}
3849+
3850+
if (PyErr_Occurred()) {
3851+
if (PyErr_ExceptionMatches(PyExc_StopIteration))
3852+
PyErr_Clear();
3853+
else {
3854+
Py_DECREF(it);
3855+
Py_XDECREF(long_cnt);
3856+
return NULL;
3857+
}
3858+
}
3859+
Py_DECREF(it);
3860+
3861+
if (long_cnt == NULL) {
3862+
return PyLong_FromSsize_t(cnt);
3863+
}
3864+
if (cnt != 0) {
3865+
new_long_cnt = PyLong_FromSsize_t(cnt);
3866+
temp = PyNumber_Add(long_cnt, new_long_cnt);
3867+
Py_SETREF(long_cnt, temp);
3868+
Py_DECREF(new_long_cnt);
3869+
}
3870+
return long_cnt;
3871+
}
3872+
3873+
38053874
/* module level code ********************************************************/
38063875

38073876
PyDoc_STRVAR(module_doc,
@@ -3951,6 +4020,7 @@ static struct PyModuleDef_Slot itertoolsmodule_slots[] = {
39514020

39524021
static PyMethodDef module_methods[] = {
39534022
ITERTOOLS_TEE_METHODDEF
4023+
ITERTOOLS_ILEN_METHODDEF
39544024
{NULL, NULL} /* sentinel */
39554025
};
39564026

0 commit comments

Comments
 (0)