asyncio: Pass cancellation from wrapping Future to wrapped Future. By Saúl Ibarra Corretgé (mostly).
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index db27838..dd3e718 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -301,6 +301,8 @@
         The other Future may be a concurrent.futures.Future.
         """
         assert other.done()
+        if self.cancelled():
+            return
         assert not self.done()
         if other.cancelled():
             self.cancel()
@@ -324,14 +326,17 @@
     """Wrap concurrent.futures.Future object."""
     if isinstance(fut, Future):
         return fut
-
     assert isinstance(fut, concurrent.futures.Future), \
         'concurrent.futures.Future is expected, got {!r}'.format(fut)
-
     if loop is None:
         loop = events.get_event_loop()
-
     new_future = Future(loop=loop)
+
+    def _check_cancel_other(f):
+        if f.cancelled():
+            fut.cancel()
+
+    new_future.add_done_callback(_check_cancel_other)
     fut.add_done_callback(
         lambda future: loop.call_soon_threadsafe(
             new_future._copy_state, fut))
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
index ccea2ff..e35fcf0 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -241,6 +241,24 @@
         f2 = futures.wrap_future(f1)
         self.assertIs(m_events.get_event_loop.return_value, f2._loop)
 
+    def test_wrap_future_cancel(self):
+        f1 = concurrent.futures.Future()
+        f2 = futures.wrap_future(f1, loop=self.loop)
+        f2.cancel()
+        test_utils.run_briefly(self.loop)
+        self.assertTrue(f1.cancelled())
+        self.assertTrue(f2.cancelled())
+
+    def test_wrap_future_cancel2(self):
+        f1 = concurrent.futures.Future()
+        f2 = futures.wrap_future(f1, loop=self.loop)
+        f1.set_result(42)
+        f2.cancel()
+        test_utils.run_briefly(self.loop)
+        self.assertFalse(f1.cancelled())
+        self.assertEqual(f1.result(), 42)
+        self.assertTrue(f2.cancelled())
+
 
 class FutureDoneCallbackTests(unittest.TestCase):