diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2020-05-15 23:55:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-15 23:55:50 (GMT) |
commit | 1ce5841eca6d96b1b1e8c213d04f2e92b1619bb5 (patch) | |
tree | 9fe492d885e1a0d660be4d96fb92b5f563aec99e /Lib/test | |
parent | fe1176e882393b6d3e6a6cfa5ca23657f0b3b4a9 (diff) | |
download | cpython-1ce5841eca6d96b1b1e8c213d04f2e92b1619bb5.zip cpython-1ce5841eca6d96b1b1e8c213d04f2e92b1619bb5.tar.gz cpython-1ce5841eca6d96b1b1e8c213d04f2e92b1619bb5.tar.bz2 |
bpo-31033: Add a msg argument to Future.cancel() and Task.cancel() (GH-19979)
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_asyncio/test_futures.py | 21 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_tasks.py | 166 |
2 files changed, 162 insertions, 25 deletions
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index ee5edd5..ec00896 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -201,6 +201,27 @@ class BaseFutureTests: self.assertFalse(fut.cancelled()) self.assertFalse(fut.done()) + def test_future_cancel_message_getter(self): + f = self._new_future(loop=self.loop) + self.assertTrue(hasattr(f, '_cancel_message')) + self.assertEqual(f._cancel_message, None) + + f.cancel('my message') + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(f) + self.assertEqual(f._cancel_message, 'my message') + + def test_future_cancel_message_setter(self): + f = self._new_future(loop=self.loop) + f.cancel('my message') + f._cancel_message = 'my new message' + self.assertEqual(f._cancel_message, 'my new message') + + # Also check that the value is used for cancel(). + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(f) + self.assertEqual(f._cancel_message, 'my new message') + def test_cancel(self): f = self._new_future(loop=self.loop) self.assertTrue(f.cancel()) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 0f8d921..65bee52 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -103,6 +103,31 @@ class BaseTaskTests: self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) + def test_task_cancel_message_getter(self): + async def coro(): + pass + t = self.new_task(self.loop, coro()) + self.assertTrue(hasattr(t, '_cancel_message')) + self.assertEqual(t._cancel_message, None) + + t.cancel('my message') + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(t) + self.assertEqual(t._cancel_message, 'my message') + + def test_task_cancel_message_setter(self): + async def coro(): + pass + t = self.new_task(self.loop, coro()) + t.cancel('my message') + t._cancel_message = 'my new message' + self.assertEqual(t._cancel_message, 'my new message') + + # Also check that the value is used for cancel(). + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(t) + self.assertEqual(t._cancel_message, 'my new message') + def test_task_del_collect(self): class Evil: def __del__(self): @@ -520,6 +545,86 @@ class BaseTaskTests: self.assertTrue(t.cancelled()) self.assertFalse(t.cancel()) + def test_cancel_with_message_then_future_result(self): + # Test Future.result() after calling cancel() with a message. + cases = [ + ((), ('',)), + ((None,), ('',)), + (('my message',), ('my message',)), + # Non-string values should roundtrip. + ((5,), (5,)), + ] + for cancel_args, expected_args in cases: + with self.subTest(cancel_args=cancel_args): + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + + async def sleep(): + await asyncio.sleep(10) + + async def coro(): + task = self.new_task(loop, sleep()) + await asyncio.sleep(0) + task.cancel(*cancel_args) + done, pending = await asyncio.wait([task]) + task.result() + + task = self.new_task(loop, coro()) + with self.assertRaises(asyncio.CancelledError) as cm: + loop.run_until_complete(task) + exc = cm.exception + self.assertEqual(exc.args, expected_args) + + def test_cancel_with_message_then_future_exception(self): + # Test Future.exception() after calling cancel() with a message. + cases = [ + ((), ('',)), + ((None,), ('',)), + (('my message',), ('my message',)), + # Non-string values should roundtrip. + ((5,), (5,)), + ] + for cancel_args, expected_args in cases: + with self.subTest(cancel_args=cancel_args): + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + + async def sleep(): + await asyncio.sleep(10) + + async def coro(): + task = self.new_task(loop, sleep()) + await asyncio.sleep(0) + task.cancel(*cancel_args) + done, pending = await asyncio.wait([task]) + task.exception() + + task = self.new_task(loop, coro()) + with self.assertRaises(asyncio.CancelledError) as cm: + loop.run_until_complete(task) + exc = cm.exception + self.assertEqual(exc.args, expected_args) + + def test_cancel_with_message_before_starting_task(self): + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + + async def sleep(): + await asyncio.sleep(10) + + async def coro(): + task = self.new_task(loop, sleep()) + # We deliberately leave out the sleep here. + task.cancel('my message') + done, pending = await asyncio.wait([task]) + task.exception() + + task = self.new_task(loop, coro()) + with self.assertRaises(asyncio.CancelledError) as cm: + loop.run_until_complete(task) + exc = cm.exception + self.assertEqual(exc.args, ('my message',)) + def test_cancel_yield(self): with self.assertWarns(DeprecationWarning): @asyncio.coroutine @@ -2285,31 +2390,42 @@ class BaseTaskTests: self.assertEqual(gather_task.result(), [42]) def test_cancel_gather_2(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def test(): - time = 0 - while True: - time += 0.05 - await asyncio.gather(asyncio.sleep(0.05), - return_exceptions=True, - loop=loop) - if time > 1: - return - - async def main(): - qwe = self.new_task(loop, test()) - await asyncio.sleep(0.2) - qwe.cancel() - try: - await qwe - except asyncio.CancelledError: - pass - else: - self.fail('gather did not propagate the cancellation request') - - loop.run_until_complete(main()) + cases = [ + ((), ('',)), + ((None,), ('',)), + (('my message',), ('my message',)), + # Non-string values should roundtrip. + ((5,), (5,)), + ] + for cancel_args, expected_args in cases: + with self.subTest(cancel_args=cancel_args): + + loop = asyncio.new_event_loop() + self.addCleanup(loop.close) + + async def test(): + time = 0 + while True: + time += 0.05 + await asyncio.gather(asyncio.sleep(0.05), + return_exceptions=True, + loop=loop) + if time > 1: + return + + async def main(): + qwe = self.new_task(loop, test()) + await asyncio.sleep(0.2) + qwe.cancel(*cancel_args) + try: + await qwe + except asyncio.CancelledError as exc: + self.assertEqual(exc.args, expected_args) + else: + self.fail('gather did not propagate the cancellation ' + 'request') + + loop.run_until_complete(main()) def test_exception_traceback(self): # See http://bugs.python.org/issue28843 |