Issue #21321: itertools.islice() now releases the reference to the source iterator when the slice is exhausted.

Patch by Anton Afanasyev.
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index 7233e7c..291aeb0 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -1,7 +1,7 @@
 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
@@ -792,6 +792,15 @@
         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
@@ -901,7 +910,7 @@
 
         # 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__')
diff --git a/Misc/ACKS b/Misc/ACKS
index 2d08627..c8c3880 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -17,6 +17,7 @@
 David Abrahams
 Marc Abramowitz
 Ron Adam
+Anton Afanasyev
 Ali Afshar
 Nitika Agarwal
 Jim Ahlstrom
diff --git a/Misc/NEWS b/Misc/NEWS
index f086cc3..ab71e01 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -46,6 +46,9 @@
 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.
 
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 @@
     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 @@
     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,