asyncio: Prevent StopIteration from being thrown into a Future

Patch by Chris Angelico (issue #26221)
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 281fea3..ddb9cde 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -341,6 +341,9 @@
             raise InvalidStateError('{}: {!r}'.format(self._state, self))
         if isinstance(exception, type):
             exception = exception()
+        if type(exception) is StopIteration:
+            raise TypeError("StopIteration interacts badly with generators "
+                            "and cannot be raised into a Future")
         self._exception = exception
         self._state = _FINISHED
         self._schedule_callbacks()
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
index 55fdff3..358b190 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -76,6 +76,10 @@
         f = asyncio.Future(loop=self.loop)
         self.assertRaises(asyncio.InvalidStateError, f.exception)
 
+        # StopIteration cannot be raised into a Future - CPython issue26221
+        self.assertRaisesRegex(TypeError, "StopIteration .* cannot be raised",
+                               f.set_exception, StopIteration)
+
         f.set_exception(exc)
         self.assertFalse(f.cancelled())
         self.assertTrue(f.done())