summaryrefslogtreecommitdiffstats
path: root/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2014-04-29 10:13:46 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2014-04-29 10:13:46 (GMT)
commit3ec903fce4c8f8f97a74b15e8a5f5599da759bc9 (patch)
tree5a71da2c8e804cbaef051fc723dbc0e9967c09df /Modules/itertoolsmodule.c
parentf3ae10e7ca9cf14299419c2c07678c7365e4b72e (diff)
downloadcpython-3ec903fce4c8f8f97a74b15e8a5f5599da759bc9.zip
cpython-3ec903fce4c8f8f97a74b15e8a5f5599da759bc9.tar.gz
cpython-3ec903fce4c8f8f97a74b15e8a5f5599da759bc9.tar.bz2
Issue #21321: itertools.islice() now releases the reference to the source iterator when the slice is exhausted.
Patch by Anton Afanasyev.
Diffstat (limited to 'Modules/itertoolsmodule.c')
-rw-r--r--Modules/itertoolsmodule.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index c0456b8..a7cd3f4 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -1241,19 +1241,22 @@ islice_next(isliceobject *lz)
Py_ssize_t oldnext;
PyObject *(*iternext)(PyObject *);
+ if (it == NULL)
+ return NULL;
+
iternext = *Py_TYPE(it)->tp_iternext;
while (lz->cnt < lz->next) {
item = iternext(it);
if (item == NULL)
- return NULL;
+ goto empty;
Py_DECREF(item);
lz->cnt++;
}
if (stop != -1 && lz->cnt >= stop)
- return NULL;
+ goto empty;
item = iternext(it);
if (item == NULL)
- return NULL;
+ goto empty;
lz->cnt++;
oldnext = lz->next;
/* The (size_t) cast below avoids the danger of undefined
@@ -1262,6 +1265,10 @@ islice_next(isliceobject *lz)
if (lz->next < oldnext || (stop != -1 && lz->next > stop))
lz->next = stop;
return item;
+
+empty:
+ Py_CLEAR(lz->it);
+ return NULL;
}
PyDoc_STRVAR(islice_doc,