merge
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 3cff72a..b6b7123 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -268,7 +268,15 @@
             future._log_destroy_pending = False
 
         future.add_done_callback(_raise_stop_error)
-        self.run_forever()
+        try:
+            self.run_forever()
+        except:
+            if new_task and future.done() and not future.cancelled():
+                # The coroutine raised a BaseException. Consume the exception
+                # to not log a warning, the caller doesn't have access to the
+                # local task.
+                future.exception()
+            raise
         future.remove_done_callback(_raise_stop_error)
         if not future.done():
             raise RuntimeError('Event loop stopped before Future completed.')
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 294872a..afc448c 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -9,7 +9,7 @@
 import unittest
 from unittest import mock
 from test.script_helper import assert_python_ok
-from test.support import IPV6_ENABLED
+from test.support import IPV6_ENABLED, gc_collect
 
 import asyncio
 from asyncio import base_events
@@ -618,6 +618,26 @@
         task._log_destroy_pending = False
         coro.close()
 
+    def test_run_forever_keyboard_interrupt(self):
+        # Python issue #22601: ensure that the temporary task created by
+        # run_forever() consumes the KeyboardInterrupt and so don't log
+        # a warning
+        @asyncio.coroutine
+        def raise_keyboard_interrupt():
+            raise KeyboardInterrupt
+
+        self.loop._process_events = mock.Mock()
+        self.loop.call_exception_handler = mock.Mock()
+
+        try:
+            self.loop.run_until_complete(raise_keyboard_interrupt())
+        except KeyboardInterrupt:
+            pass
+        self.loop.close()
+        gc_collect()
+
+        self.assertFalse(self.loop.call_exception_handler.called)
+
 
 class MyProto(asyncio.Protocol):
     done = None