How to cancel a task, even if it ignores a CanceledError?

This is an example of canceling a task:

import asyncio async def some_func(): await asyncio.sleep(2) print('Haha! Task keeps running!') await asyncio.sleep(2) async def cancel(task): await asyncio.sleep(1) task.cancel() async def main(): func_task = asyncio.ensure_future(some_func()) cancel_task = asyncio.ensure_future(cancel(func_task)) try: await func_task except asyncio.CancelledError: print('Task cancelled as expected') if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) # Task cancelled as expected # [Finished in 1.2s] 

It works fine, the task has been canceled. If a CancelledError that some_func inside the some_func task is not canceled:

 async def some_func(): try: await asyncio.sleep(2) except: pass print('Haha! Task keeps running!') await asyncio.sleep(2) # Haha! Task keeps running! # [Finished in 3.2s] 

You can easily forget that I should not suppress exceptions anywhere inside the asynchronous code (or some_func can be, for example, third-party code), but the task should be canceled. Anyway, can I do this? Or is ignored a CancelledError meaning the task cannot be canceled at all?

+1
source share
1 answer

You cannot undo a task that suppresses a CancelledError . This is close to being unable to close a generator that ignores GeneratorExit .

This is intentional behavior. A task may require additional work (such as cleaning up resources) during cancellation, so catching a CancelledError may be a good idea, but suppression is usually a sign of a programming error.

Python usually allows you to take your own legs off if you have an uncompromising intention of doing this.

Capturing all exceptions even prohibits closing the python process by clicking because it is translated into KeyboardInterrupt internally.

+3
source

Source: https://habr.com/ru/post/1270523/


All Articles