diff options
Diffstat (limited to 'Lib/test/test_asyncio/test_runners.py')
-rw-r--r-- | Lib/test/test_asyncio/test_runners.py | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 94f26797b3..42aa07a0e0 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -1,7 +1,9 @@ +import _thread import asyncio import contextvars import gc import re +import threading import unittest from unittest import mock @@ -12,6 +14,10 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) +def interrupt_self(): + _thread.interrupt_main() + + class TestPolicy(asyncio.AbstractEventLoopPolicy): def __init__(self, loop_factory): @@ -298,7 +304,7 @@ class RunnerTests(BaseTest): self.assertEqual(2, runner.run(get_context()).get(cvar)) - def test_recursine_run(self): + def test_recursive_run(self): async def g(): pass @@ -318,6 +324,57 @@ class RunnerTests(BaseTest): ): runner.run(f()) + def test_interrupt_call_soon(self): + # The only case when task is not suspended by waiting a future + # or another task + assert threading.current_thread() is threading.main_thread() + + async def coro(): + with self.assertRaises(asyncio.CancelledError): + while True: + await asyncio.sleep(0) + raise asyncio.CancelledError() + + with asyncio.Runner() as runner: + runner.get_loop().call_later(0.1, interrupt_self) + with self.assertRaises(KeyboardInterrupt): + runner.run(coro()) + + def test_interrupt_wait(self): + # interrupting when waiting a future cancels both future and main task + assert threading.current_thread() is threading.main_thread() + + async def coro(fut): + with self.assertRaises(asyncio.CancelledError): + await fut + raise asyncio.CancelledError() + + with asyncio.Runner() as runner: + fut = runner.get_loop().create_future() + runner.get_loop().call_later(0.1, interrupt_self) + + with self.assertRaises(KeyboardInterrupt): + runner.run(coro(fut)) + + self.assertTrue(fut.cancelled()) + + def test_interrupt_cancelled_task(self): + # interrupting cancelled main task doesn't raise KeyboardInterrupt + assert threading.current_thread() is threading.main_thread() + + async def subtask(task): + await asyncio.sleep(0) + task.cancel() + interrupt_self() + + async def coro(): + asyncio.create_task(subtask(asyncio.current_task())) + await asyncio.sleep(10) + + with asyncio.Runner() as runner: + with self.assertRaises(asyncio.CancelledError): + runner.run(coro()) + if __name__ == '__main__': unittest.main() |