aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_asyncio/test_taskgroups.py66
-rw-r--r--Lib/test/test_asyncio/test_tasks.py24
2 files changed, 90 insertions, 0 deletions
diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py
index 1ec8116953f..4852536defc 100644
--- a/Lib/test/test_asyncio/test_taskgroups.py
+++ b/Lib/test/test_asyncio/test_taskgroups.py
@@ -833,6 +833,72 @@ class TestTaskGroup(unittest.IsolatedAsyncioTestCase):
loop = asyncio.get_event_loop()
loop.run_until_complete(run_coro_after_tg_closes())
+ async def test_cancelling_level_preserved(self):
+ async def raise_after(t, e):
+ await asyncio.sleep(t)
+ raise e()
+
+ try:
+ async with asyncio.TaskGroup() as tg:
+ tg.create_task(raise_after(0.0, RuntimeError))
+ except* RuntimeError:
+ pass
+ self.assertEqual(asyncio.current_task().cancelling(), 0)
+
+ async def test_nested_groups_both_cancelled(self):
+ async def raise_after(t, e):
+ await asyncio.sleep(t)
+ raise e()
+
+ try:
+ async with asyncio.TaskGroup() as outer_tg:
+ try:
+ async with asyncio.TaskGroup() as inner_tg:
+ inner_tg.create_task(raise_after(0, RuntimeError))
+ outer_tg.create_task(raise_after(0, ValueError))
+ except* RuntimeError:
+ pass
+ else:
+ self.fail("RuntimeError not raised")
+ self.assertEqual(asyncio.current_task().cancelling(), 1)
+ except* ValueError:
+ pass
+ else:
+ self.fail("ValueError not raised")
+ self.assertEqual(asyncio.current_task().cancelling(), 0)
+
+ async def test_error_and_cancel(self):
+ event = asyncio.Event()
+
+ async def raise_error():
+ event.set()
+ await asyncio.sleep(0)
+ raise RuntimeError()
+
+ async def inner():
+ try:
+ async with taskgroups.TaskGroup() as tg:
+ tg.create_task(raise_error())
+ await asyncio.sleep(1)
+ self.fail("Sleep in group should have been cancelled")
+ except* RuntimeError:
+ self.assertEqual(asyncio.current_task().cancelling(), 1)
+ self.assertEqual(asyncio.current_task().cancelling(), 1)
+ await asyncio.sleep(1)
+ self.fail("Sleep after group should have been cancelled")
+
+ async def outer():
+ t = asyncio.create_task(inner())
+ await event.wait()
+ self.assertEqual(t.cancelling(), 0)
+ t.cancel()
+ self.assertEqual(t.cancelling(), 1)
+ with self.assertRaises(asyncio.CancelledError):
+ await t
+ self.assertTrue(t.cancelled())
+
+ await outer()
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index bc6d88e65a4..5b09c81faef 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -684,6 +684,30 @@ class BaseTaskTests:
finally:
loop.close()
+ def test_uncancel_resets_must_cancel(self):
+
+ async def coro():
+ await fut
+ return 42
+
+ loop = asyncio.new_event_loop()
+ fut = asyncio.Future(loop=loop)
+ task = self.new_task(loop, coro())
+ loop.run_until_complete(asyncio.sleep(0)) # Get task waiting for fut
+ fut.set_result(None) # Make task runnable
+ try:
+ task.cancel() # Enter cancelled state
+ self.assertEqual(task.cancelling(), 1)
+ self.assertTrue(task._must_cancel)
+
+ task.uncancel() # Undo cancellation
+ self.assertEqual(task.cancelling(), 0)
+ self.assertFalse(task._must_cancel)
+ finally:
+ res = loop.run_until_complete(task)
+ self.assertEqual(res, 42)
+ loop.close()
+
def test_cancel(self):
def gen():