10000 Pass cancellation from wrapping Future to wrapped Future. Fixes issue… · Python-Repository-Hub/asyncio@6702599 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6702599

Browse files
committed
Pass cancellation from wrapping Future to wrapped Future. Fixes issue 88. By Sa?l Ibarra Corretg? (mostly).
1 parent 8307a7f commit 6702599

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

asyncio/futures.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ def _copy_state(self, other):
301301
The other Future may be a concurrent.futures.Future.
302302
"""
303303
assert other.done()
304+
if self.cancelled():
305+
return
304306
assert not self.done()
305307
if other.cancelled():
306308
self.cancel()
@@ -324,14 +326,17 @@ def wrap_future(fut, *, loop=None):
324326
"""Wrap concurrent.futures.Future object."""
325327
if isinstance(fut, Future):
326328
return fut
327-
328329
assert isinstance(fut, concurrent.futures.Future), \
329330
'concurrent.futures.Future is expected, got {!r}'.format(fut)
330-
331331
if loop is None:
332332
loop = events.get_event_loop()
333-
334333
new_future = Future(loop=loop)
334+
335+
def _check_cancel_other(f):
336+
if f.cancelled():
337+
fut.cancel()
338+
339+
new_future.add_done_callback(_check_cancel_other)
335340
fut.add_done_callback(
336341
lambda future: loop.call_soon_threadsafe(
337342
new_future._copy_state, fut))

tests/test_futures.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,24 @@ def run(arg):
241241
f2 = futures.wrap_future(f1)
242242
self.assertIs(m_events.get_event_loop.return_value, f2._loop)
243243

244+
def test_wrap_future_cancel(self):
245+
f1 = concurrent.futures.Future()
246+
f2 = futures.wrap_future(f1, loop=self.loop)
247+
f2.cancel()
248+
test_utils.run_briefly(self.loop)
249+
self.assertTrue(f1.cancelled())
250+
self.assertTrue(f2.cancelled())
251+
252+
def test_wrap_future_cancel2(self):
253+
f1 = concurrent.futures.Future()
254+
f2 = futures.wrap_future(f1, loop=self.loop)
255+
f1.set_result(42)
256+
f2.cancel()
257+
test_utils.run_briefly(self.loop)
258+
self.assertFalse(f1.cancelled())
259+
self.assertEqual(f1.result(), 42)
260+
self.assertTrue(f2.cancelled())
261+
244262

245263
class FutureDoneCallbackTests(unittest.TestCase):
246264

0 commit comments

Comments
 (0)
0