import unittest
from test import test_support
from itertools import *
-from weakref import proxy
+import weakref
from decimal import Decimal
from fractions import Fraction
import sys
self.assertEqual(list(islice(c, 1, 3, 50)), [1])
self.assertEqual(next(c), 3)
+ # Issue #21321: check source iterator is not referenced
+ # from islice() after the latter has been exhausted
+ it = (x for x in (1, 2))
+ wr = weakref.ref(it)
+ it = islice(it, 1)
+ self.assertIsNotNone(wr())
+ list(it) # exhaust the iterator
+ self.assertIsNone(wr())
+
def test_takewhile(self):
data = [1, 3, 5, 20, 2, 4, 6, 8]
underten = lambda x: x<10
# test that tee objects are weak referencable
a, b = tee(xrange(10))
- p = proxy(a)
+ p = weakref.proxy(a)
self.assertEqual(getattr(p, '__class__'), type(b))
del a
self.assertRaises(ReferenceError, getattr, p, '__class__')
Library
-------
+- Issue #21321: itertools.islice() now releases the reference to the source
+ iterator when the slice is exhausted. Patch by Anton Afanasyev.
+
- Issue #9291: Do not attempt to re-encode mimetype data read from registry in
ANSI mode. Initial patches by Dmitry Jemerov & Vladimir Iofik.
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
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,