17db96d56Sopenharmony_ci.. currentmodule:: asyncio 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci==================== 57db96d56Sopenharmony_ciCoroutines and Tasks 67db96d56Sopenharmony_ci==================== 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ciThis section outlines high-level asyncio APIs to work with coroutines 97db96d56Sopenharmony_ciand Tasks. 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci.. contents:: 127db96d56Sopenharmony_ci :depth: 1 137db96d56Sopenharmony_ci :local: 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci.. _coroutine: 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ciCoroutines 197db96d56Sopenharmony_ci========== 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/coroutines.py` 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci---------------------------------------------------- 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci:term:`Coroutines <coroutine>` declared with the async/await syntax is the 267db96d56Sopenharmony_cipreferred way of writing asyncio applications. For example, the following 277db96d56Sopenharmony_cisnippet of code prints "hello", waits 1 second, 287db96d56Sopenharmony_ciand then prints "world":: 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci >>> import asyncio 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci >>> async def main(): 337db96d56Sopenharmony_ci ... print('hello') 347db96d56Sopenharmony_ci ... await asyncio.sleep(1) 357db96d56Sopenharmony_ci ... print('world') 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci >>> asyncio.run(main()) 387db96d56Sopenharmony_ci hello 397db96d56Sopenharmony_ci world 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ciNote that simply calling a coroutine will not schedule it to 427db96d56Sopenharmony_cibe executed:: 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci >>> main() 457db96d56Sopenharmony_ci <coroutine object main at 0x1053bb7c8> 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ciTo actually run a coroutine, asyncio provides the following mechanisms: 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci* The :func:`asyncio.run` function to run the top-level 507db96d56Sopenharmony_ci entry point "main()" function (see the above example.) 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci* Awaiting on a coroutine. The following snippet of code will 537db96d56Sopenharmony_ci print "hello" after waiting for 1 second, and then print "world" 547db96d56Sopenharmony_ci after waiting for *another* 2 seconds:: 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci import asyncio 577db96d56Sopenharmony_ci import time 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci async def say_after(delay, what): 607db96d56Sopenharmony_ci await asyncio.sleep(delay) 617db96d56Sopenharmony_ci print(what) 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci async def main(): 647db96d56Sopenharmony_ci print(f"started at {time.strftime('%X')}") 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci await say_after(1, 'hello') 677db96d56Sopenharmony_ci await say_after(2, 'world') 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci print(f"finished at {time.strftime('%X')}") 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci asyncio.run(main()) 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci Expected output:: 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci started at 17:13:52 767db96d56Sopenharmony_ci hello 777db96d56Sopenharmony_ci world 787db96d56Sopenharmony_ci finished at 17:13:55 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci* The :func:`asyncio.create_task` function to run coroutines 817db96d56Sopenharmony_ci concurrently as asyncio :class:`Tasks <Task>`. 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci Let's modify the above example and run two ``say_after`` coroutines 847db96d56Sopenharmony_ci *concurrently*:: 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci async def main(): 877db96d56Sopenharmony_ci task1 = asyncio.create_task( 887db96d56Sopenharmony_ci say_after(1, 'hello')) 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci task2 = asyncio.create_task( 917db96d56Sopenharmony_ci say_after(2, 'world')) 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci print(f"started at {time.strftime('%X')}") 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci # Wait until both tasks are completed (should take 967db96d56Sopenharmony_ci # around 2 seconds.) 977db96d56Sopenharmony_ci await task1 987db96d56Sopenharmony_ci await task2 997db96d56Sopenharmony_ci 1007db96d56Sopenharmony_ci print(f"finished at {time.strftime('%X')}") 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci Note that expected output now shows that the snippet runs 1037db96d56Sopenharmony_ci 1 second faster than before:: 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci started at 17:14:32 1067db96d56Sopenharmony_ci hello 1077db96d56Sopenharmony_ci world 1087db96d56Sopenharmony_ci finished at 17:14:34 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci* The :class:`asyncio.TaskGroup` class provides a more modern 1117db96d56Sopenharmony_ci alternative to :func:`create_task`. 1127db96d56Sopenharmony_ci Using this API, the last example becomes:: 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci async def main(): 1157db96d56Sopenharmony_ci async with asyncio.TaskGroup() as tg: 1167db96d56Sopenharmony_ci task1 = tg.create_task( 1177db96d56Sopenharmony_ci say_after(1, 'hello')) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci task2 = tg.create_task( 1207db96d56Sopenharmony_ci say_after(2, 'world')) 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci print(f"started at {time.strftime('%X')}") 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci # The await is implicit when the context manager exits. 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci print(f"finished at {time.strftime('%X')}") 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci The timing and output should be the same as for the previous version. 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci .. versionadded:: 3.11 1317db96d56Sopenharmony_ci :class:`asyncio.TaskGroup`. 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci.. _asyncio-awaitables: 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ciAwaitables 1377db96d56Sopenharmony_ci========== 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ciWe say that an object is an **awaitable** object if it can be used 1407db96d56Sopenharmony_ciin an :keyword:`await` expression. Many asyncio APIs are designed to 1417db96d56Sopenharmony_ciaccept awaitables. 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ciThere are three main types of *awaitable* objects: 1447db96d56Sopenharmony_ci**coroutines**, **Tasks**, and **Futures**. 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci.. rubric:: Coroutines 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ciPython coroutines are *awaitables* and therefore can be awaited from 1507db96d56Sopenharmony_ciother coroutines:: 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci import asyncio 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci async def nested(): 1557db96d56Sopenharmony_ci return 42 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci async def main(): 1587db96d56Sopenharmony_ci # Nothing happens if we just call "nested()". 1597db96d56Sopenharmony_ci # A coroutine object is created but not awaited, 1607db96d56Sopenharmony_ci # so it *won't run at all*. 1617db96d56Sopenharmony_ci nested() 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci # Let's do it differently now and await it: 1647db96d56Sopenharmony_ci print(await nested()) # will print "42". 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_ci asyncio.run(main()) 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci.. important:: 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci In this documentation the term "coroutine" can be used for 1717db96d56Sopenharmony_ci two closely related concepts: 1727db96d56Sopenharmony_ci 1737db96d56Sopenharmony_ci * a *coroutine function*: an :keyword:`async def` function; 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci * a *coroutine object*: an object returned by calling a 1767db96d56Sopenharmony_ci *coroutine function*. 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci.. rubric:: Tasks 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci*Tasks* are used to schedule coroutines *concurrently*. 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ciWhen a coroutine is wrapped into a *Task* with functions like 1847db96d56Sopenharmony_ci:func:`asyncio.create_task` the coroutine is automatically 1857db96d56Sopenharmony_cischeduled to run soon:: 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ci import asyncio 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci async def nested(): 1907db96d56Sopenharmony_ci return 42 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci async def main(): 1937db96d56Sopenharmony_ci # Schedule nested() to run soon concurrently 1947db96d56Sopenharmony_ci # with "main()". 1957db96d56Sopenharmony_ci task = asyncio.create_task(nested()) 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci # "task" can now be used to cancel "nested()", or 1987db96d56Sopenharmony_ci # can simply be awaited to wait until it is complete: 1997db96d56Sopenharmony_ci await task 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci asyncio.run(main()) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci.. rubric:: Futures 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ciA :class:`Future` is a special **low-level** awaitable object that 2077db96d56Sopenharmony_cirepresents an **eventual result** of an asynchronous operation. 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ciWhen a Future object is *awaited* it means that the coroutine will 2107db96d56Sopenharmony_ciwait until the Future is resolved in some other place. 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ciFuture objects in asyncio are needed to allow callback-based code 2137db96d56Sopenharmony_cito be used with async/await. 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ciNormally **there is no need** to create Future objects at the 2167db96d56Sopenharmony_ciapplication level code. 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ciFuture objects, sometimes exposed by libraries and some asyncio 2197db96d56Sopenharmony_ciAPIs, can be awaited:: 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci async def main(): 2227db96d56Sopenharmony_ci await function_that_returns_a_future_object() 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci # this is also valid: 2257db96d56Sopenharmony_ci await asyncio.gather( 2267db96d56Sopenharmony_ci function_that_returns_a_future_object(), 2277db96d56Sopenharmony_ci some_python_coroutine() 2287db96d56Sopenharmony_ci ) 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ciA good example of a low-level function that returns a Future object 2317db96d56Sopenharmony_ciis :meth:`loop.run_in_executor`. 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ciCreating Tasks 2357db96d56Sopenharmony_ci============== 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/tasks.py` 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci----------------------------------------------- 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_ci.. function:: create_task(coro, *, name=None, context=None) 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci Wrap the *coro* :ref:`coroutine <coroutine>` into a :class:`Task` 2447db96d56Sopenharmony_ci and schedule its execution. Return the Task object. 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci If *name* is not ``None``, it is set as the name of the task using 2477db96d56Sopenharmony_ci :meth:`Task.set_name`. 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci An optional keyword-only *context* argument allows specifying a 2507db96d56Sopenharmony_ci custom :class:`contextvars.Context` for the *coro* to run in. 2517db96d56Sopenharmony_ci The current context copy is created when no *context* is provided. 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci The task is executed in the loop returned by :func:`get_running_loop`, 2547db96d56Sopenharmony_ci :exc:`RuntimeError` is raised if there is no running loop in 2557db96d56Sopenharmony_ci current thread. 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci .. note:: 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci :meth:`asyncio.TaskGroup.create_task` is a newer alternative 2607db96d56Sopenharmony_ci that allows for convenient waiting for a group of related tasks. 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci .. important:: 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_ci Save a reference to the result of this function, to avoid 2657db96d56Sopenharmony_ci a task disappearing mid-execution. The event loop only keeps 2667db96d56Sopenharmony_ci weak references to tasks. A task that isn't referenced elsewhere 2677db96d56Sopenharmony_ci may get garbage collected at any time, even before it's done. 2687db96d56Sopenharmony_ci For reliable "fire-and-forget" background tasks, gather them in 2697db96d56Sopenharmony_ci a collection:: 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci background_tasks = set() 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ci for i in range(10): 2747db96d56Sopenharmony_ci task = asyncio.create_task(some_coro(param=i)) 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci # Add task to the set. This creates a strong reference. 2777db96d56Sopenharmony_ci background_tasks.add(task) 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ci # To prevent keeping references to finished tasks forever, 2807db96d56Sopenharmony_ci # make each task remove its own reference from the set after 2817db96d56Sopenharmony_ci # completion: 2827db96d56Sopenharmony_ci task.add_done_callback(background_tasks.discard) 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci .. versionadded:: 3.7 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci .. versionchanged:: 3.8 2877db96d56Sopenharmony_ci Added the *name* parameter. 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci .. versionchanged:: 3.11 2907db96d56Sopenharmony_ci Added the *context* parameter. 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ciTask Cancellation 2947db96d56Sopenharmony_ci================= 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ciTasks can easily and safely be cancelled. 2977db96d56Sopenharmony_ciWhen a task is cancelled, :exc:`asyncio.CancelledError` will be raised 2987db96d56Sopenharmony_ciin the task at the next opportunity. 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ciIt is recommended that coroutines use ``try/finally`` blocks to robustly 3017db96d56Sopenharmony_ciperform clean-up logic. In case :exc:`asyncio.CancelledError` 3027db96d56Sopenharmony_ciis explicitly caught, it should generally be propagated when 3037db96d56Sopenharmony_ciclean-up is complete. :exc:`asyncio.CancelledError` directly subclasses 3047db96d56Sopenharmony_ci:exc:`BaseException` so most code will not need to be aware of it. 3057db96d56Sopenharmony_ci 3067db96d56Sopenharmony_ciThe asyncio components that enable structured concurrency, like 3077db96d56Sopenharmony_ci:class:`asyncio.TaskGroup` and :func:`asyncio.timeout`, 3087db96d56Sopenharmony_ciare implemented using cancellation internally and might misbehave if 3097db96d56Sopenharmony_cia coroutine swallows :exc:`asyncio.CancelledError`. Similarly, user code 3107db96d56Sopenharmony_cishould not generally call :meth:`uncancel <asyncio.Task.uncancel>`. 3117db96d56Sopenharmony_ciHowever, in cases when suppressing :exc:`asyncio.CancelledError` is 3127db96d56Sopenharmony_citruly desired, it is necessary to also call ``uncancel()`` to completely 3137db96d56Sopenharmony_ciremove the cancellation state. 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci.. _taskgroups: 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ciTask Groups 3187db96d56Sopenharmony_ci=========== 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ciTask groups combine a task creation API with a convenient 3217db96d56Sopenharmony_ciand reliable way to wait for all tasks in the group to finish. 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci.. class:: TaskGroup() 3247db96d56Sopenharmony_ci 3257db96d56Sopenharmony_ci An :ref:`asynchronous context manager <async-context-managers>` 3267db96d56Sopenharmony_ci holding a group of tasks. 3277db96d56Sopenharmony_ci Tasks can be added to the group using :meth:`create_task`. 3287db96d56Sopenharmony_ci All tasks are awaited when the context manager exits. 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci .. versionadded:: 3.11 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci .. method:: create_task(coro, *, name=None, context=None) 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci Create a task in this task group. 3357db96d56Sopenharmony_ci The signature matches that of :func:`asyncio.create_task`. 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ciExample:: 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ci async def main(): 3407db96d56Sopenharmony_ci async with asyncio.TaskGroup() as tg: 3417db96d56Sopenharmony_ci task1 = tg.create_task(some_coro(...)) 3427db96d56Sopenharmony_ci task2 = tg.create_task(another_coro(...)) 3437db96d56Sopenharmony_ci print("Both tasks have completed now.") 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ciThe ``async with`` statement will wait for all tasks in the group to finish. 3467db96d56Sopenharmony_ciWhile waiting, new tasks may still be added to the group 3477db96d56Sopenharmony_ci(for example, by passing ``tg`` into one of the coroutines 3487db96d56Sopenharmony_ciand calling ``tg.create_task()`` in that coroutine). 3497db96d56Sopenharmony_ciOnce the last task has finished and the ``async with`` block is exited, 3507db96d56Sopenharmony_cino new tasks may be added to the group. 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ciThe first time any of the tasks belonging to the group fails 3537db96d56Sopenharmony_ciwith an exception other than :exc:`asyncio.CancelledError`, 3547db96d56Sopenharmony_cithe remaining tasks in the group are cancelled. 3557db96d56Sopenharmony_ciNo further tasks can then be added to the group. 3567db96d56Sopenharmony_ciAt this point, if the body of the ``async with`` statement is still active 3577db96d56Sopenharmony_ci(i.e., :meth:`~object.__aexit__` hasn't been called yet), 3587db96d56Sopenharmony_cithe task directly containing the ``async with`` statement is also cancelled. 3597db96d56Sopenharmony_ciThe resulting :exc:`asyncio.CancelledError` will interrupt an ``await``, 3607db96d56Sopenharmony_cibut it will not bubble out of the containing ``async with`` statement. 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ciOnce all tasks have finished, if any tasks have failed 3637db96d56Sopenharmony_ciwith an exception other than :exc:`asyncio.CancelledError`, 3647db96d56Sopenharmony_cithose exceptions are combined in an 3657db96d56Sopenharmony_ci:exc:`ExceptionGroup` or :exc:`BaseExceptionGroup` 3667db96d56Sopenharmony_ci(as appropriate; see their documentation) 3677db96d56Sopenharmony_ciwhich is then raised. 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ciTwo base exceptions are treated specially: 3707db96d56Sopenharmony_ciIf any task fails with :exc:`KeyboardInterrupt` or :exc:`SystemExit`, 3717db96d56Sopenharmony_cithe task group still cancels the remaining tasks and waits for them, 3727db96d56Sopenharmony_cibut then the initial :exc:`KeyboardInterrupt` or :exc:`SystemExit` 3737db96d56Sopenharmony_ciis re-raised instead of :exc:`ExceptionGroup` or :exc:`BaseExceptionGroup`. 3747db96d56Sopenharmony_ci 3757db96d56Sopenharmony_ciIf the body of the ``async with`` statement exits with an exception 3767db96d56Sopenharmony_ci(so :meth:`~object.__aexit__` is called with an exception set), 3777db96d56Sopenharmony_cithis is treated the same as if one of the tasks failed: 3787db96d56Sopenharmony_cithe remaining tasks are cancelled and then waited for, 3797db96d56Sopenharmony_ciand non-cancellation exceptions are grouped into an 3807db96d56Sopenharmony_ciexception group and raised. 3817db96d56Sopenharmony_ciThe exception passed into :meth:`~object.__aexit__`, 3827db96d56Sopenharmony_ciunless it is :exc:`asyncio.CancelledError`, 3837db96d56Sopenharmony_ciis also included in the exception group. 3847db96d56Sopenharmony_ciThe same special case is made for 3857db96d56Sopenharmony_ci:exc:`KeyboardInterrupt` and :exc:`SystemExit` as in the previous paragraph. 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ciSleeping 3897db96d56Sopenharmony_ci======== 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci.. coroutinefunction:: sleep(delay, result=None) 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci Block for *delay* seconds. 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_ci If *result* is provided, it is returned to the caller 3967db96d56Sopenharmony_ci when the coroutine completes. 3977db96d56Sopenharmony_ci 3987db96d56Sopenharmony_ci ``sleep()`` always suspends the current task, allowing other tasks 3997db96d56Sopenharmony_ci to run. 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci Setting the delay to 0 provides an optimized path to allow other 4027db96d56Sopenharmony_ci tasks to run. This can be used by long-running functions to avoid 4037db96d56Sopenharmony_ci blocking the event loop for the full duration of the function call. 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci .. _asyncio_example_sleep: 4067db96d56Sopenharmony_ci 4077db96d56Sopenharmony_ci Example of coroutine displaying the current date every second 4087db96d56Sopenharmony_ci for 5 seconds:: 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_ci import asyncio 4117db96d56Sopenharmony_ci import datetime 4127db96d56Sopenharmony_ci 4137db96d56Sopenharmony_ci async def display_date(): 4147db96d56Sopenharmony_ci loop = asyncio.get_running_loop() 4157db96d56Sopenharmony_ci end_time = loop.time() + 5.0 4167db96d56Sopenharmony_ci while True: 4177db96d56Sopenharmony_ci print(datetime.datetime.now()) 4187db96d56Sopenharmony_ci if (loop.time() + 1.0) >= end_time: 4197db96d56Sopenharmony_ci break 4207db96d56Sopenharmony_ci await asyncio.sleep(1) 4217db96d56Sopenharmony_ci 4227db96d56Sopenharmony_ci asyncio.run(display_date()) 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci 4257db96d56Sopenharmony_ci .. versionchanged:: 3.10 4267db96d56Sopenharmony_ci Removed the *loop* parameter. 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ciRunning Tasks Concurrently 4307db96d56Sopenharmony_ci========================== 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_ci.. awaitablefunction:: gather(*aws, return_exceptions=False) 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_ci Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws* 4357db96d56Sopenharmony_ci sequence *concurrently*. 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_ci If any awaitable in *aws* is a coroutine, it is automatically 4387db96d56Sopenharmony_ci scheduled as a Task. 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ci If all awaitables are completed successfully, the result is an 4417db96d56Sopenharmony_ci aggregate list of returned values. The order of result values 4427db96d56Sopenharmony_ci corresponds to the order of awaitables in *aws*. 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_ci If *return_exceptions* is ``False`` (default), the first 4457db96d56Sopenharmony_ci raised exception is immediately propagated to the task that 4467db96d56Sopenharmony_ci awaits on ``gather()``. Other awaitables in the *aws* sequence 4477db96d56Sopenharmony_ci **won't be cancelled** and will continue to run. 4487db96d56Sopenharmony_ci 4497db96d56Sopenharmony_ci If *return_exceptions* is ``True``, exceptions are treated the 4507db96d56Sopenharmony_ci same as successful results, and aggregated in the result list. 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci If ``gather()`` is *cancelled*, all submitted awaitables 4537db96d56Sopenharmony_ci (that have not completed yet) are also *cancelled*. 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci If any Task or Future from the *aws* sequence is *cancelled*, it is 4567db96d56Sopenharmony_ci treated as if it raised :exc:`CancelledError` -- the ``gather()`` 4577db96d56Sopenharmony_ci call is **not** cancelled in this case. This is to prevent the 4587db96d56Sopenharmony_ci cancellation of one submitted Task/Future to cause other 4597db96d56Sopenharmony_ci Tasks/Futures to be cancelled. 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci .. note:: 4627db96d56Sopenharmony_ci A more modern way to create and run tasks concurrently and 4637db96d56Sopenharmony_ci wait for their completion is :class:`asyncio.TaskGroup`. 4647db96d56Sopenharmony_ci 4657db96d56Sopenharmony_ci .. _asyncio_example_gather: 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ci Example:: 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_ci import asyncio 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci async def factorial(name, number): 4727db96d56Sopenharmony_ci f = 1 4737db96d56Sopenharmony_ci for i in range(2, number + 1): 4747db96d56Sopenharmony_ci print(f"Task {name}: Compute factorial({number}), currently i={i}...") 4757db96d56Sopenharmony_ci await asyncio.sleep(1) 4767db96d56Sopenharmony_ci f *= i 4777db96d56Sopenharmony_ci print(f"Task {name}: factorial({number}) = {f}") 4787db96d56Sopenharmony_ci return f 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_ci async def main(): 4817db96d56Sopenharmony_ci # Schedule three calls *concurrently*: 4827db96d56Sopenharmony_ci L = await asyncio.gather( 4837db96d56Sopenharmony_ci factorial("A", 2), 4847db96d56Sopenharmony_ci factorial("B", 3), 4857db96d56Sopenharmony_ci factorial("C", 4), 4867db96d56Sopenharmony_ci ) 4877db96d56Sopenharmony_ci print(L) 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_ci asyncio.run(main()) 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci # Expected output: 4927db96d56Sopenharmony_ci # 4937db96d56Sopenharmony_ci # Task A: Compute factorial(2), currently i=2... 4947db96d56Sopenharmony_ci # Task B: Compute factorial(3), currently i=2... 4957db96d56Sopenharmony_ci # Task C: Compute factorial(4), currently i=2... 4967db96d56Sopenharmony_ci # Task A: factorial(2) = 2 4977db96d56Sopenharmony_ci # Task B: Compute factorial(3), currently i=3... 4987db96d56Sopenharmony_ci # Task C: Compute factorial(4), currently i=3... 4997db96d56Sopenharmony_ci # Task B: factorial(3) = 6 5007db96d56Sopenharmony_ci # Task C: Compute factorial(4), currently i=4... 5017db96d56Sopenharmony_ci # Task C: factorial(4) = 24 5027db96d56Sopenharmony_ci # [2, 6, 24] 5037db96d56Sopenharmony_ci 5047db96d56Sopenharmony_ci .. note:: 5057db96d56Sopenharmony_ci If *return_exceptions* is False, cancelling gather() after it 5067db96d56Sopenharmony_ci has been marked done won't cancel any submitted awaitables. 5077db96d56Sopenharmony_ci For instance, gather can be marked done after propagating an 5087db96d56Sopenharmony_ci exception to the caller, therefore, calling ``gather.cancel()`` 5097db96d56Sopenharmony_ci after catching an exception (raised by one of the awaitables) from 5107db96d56Sopenharmony_ci gather won't cancel any other awaitables. 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_ci .. versionchanged:: 3.7 5137db96d56Sopenharmony_ci If the *gather* itself is cancelled, the cancellation is 5147db96d56Sopenharmony_ci propagated regardless of *return_exceptions*. 5157db96d56Sopenharmony_ci 5167db96d56Sopenharmony_ci .. versionchanged:: 3.10 5177db96d56Sopenharmony_ci Removed the *loop* parameter. 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_ci .. deprecated:: 3.10 5207db96d56Sopenharmony_ci Deprecation warning is emitted if no positional arguments are provided 5217db96d56Sopenharmony_ci or not all positional arguments are Future-like objects 5227db96d56Sopenharmony_ci and there is no running event loop. 5237db96d56Sopenharmony_ci 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_ciShielding From Cancellation 5267db96d56Sopenharmony_ci=========================== 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ci.. awaitablefunction:: shield(aw) 5297db96d56Sopenharmony_ci 5307db96d56Sopenharmony_ci Protect an :ref:`awaitable object <asyncio-awaitables>` 5317db96d56Sopenharmony_ci from being :meth:`cancelled <Task.cancel>`. 5327db96d56Sopenharmony_ci 5337db96d56Sopenharmony_ci If *aw* is a coroutine it is automatically scheduled as a Task. 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_ci The statement:: 5367db96d56Sopenharmony_ci 5377db96d56Sopenharmony_ci task = asyncio.create_task(something()) 5387db96d56Sopenharmony_ci res = await shield(task) 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ci is equivalent to:: 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci res = await something() 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_ci *except* that if the coroutine containing it is cancelled, the 5457db96d56Sopenharmony_ci Task running in ``something()`` is not cancelled. From the point 5467db96d56Sopenharmony_ci of view of ``something()``, the cancellation did not happen. 5477db96d56Sopenharmony_ci Although its caller is still cancelled, so the "await" expression 5487db96d56Sopenharmony_ci still raises a :exc:`CancelledError`. 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci If ``something()`` is cancelled by other means (i.e. from within 5517db96d56Sopenharmony_ci itself) that would also cancel ``shield()``. 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_ci If it is desired to completely ignore cancellation (not recommended) 5547db96d56Sopenharmony_ci the ``shield()`` function should be combined with a try/except 5557db96d56Sopenharmony_ci clause, as follows:: 5567db96d56Sopenharmony_ci 5577db96d56Sopenharmony_ci task = asyncio.create_task(something()) 5587db96d56Sopenharmony_ci try: 5597db96d56Sopenharmony_ci res = await shield(task) 5607db96d56Sopenharmony_ci except CancelledError: 5617db96d56Sopenharmony_ci res = None 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_ci .. important:: 5647db96d56Sopenharmony_ci 5657db96d56Sopenharmony_ci Save a reference to tasks passed to this function, to avoid 5667db96d56Sopenharmony_ci a task disappearing mid-execution. The event loop only keeps 5677db96d56Sopenharmony_ci weak references to tasks. A task that isn't referenced elsewhere 5687db96d56Sopenharmony_ci may get garbage collected at any time, even before it's done. 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci .. versionchanged:: 3.10 5717db96d56Sopenharmony_ci Removed the *loop* parameter. 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ci .. deprecated:: 3.10 5747db96d56Sopenharmony_ci Deprecation warning is emitted if *aw* is not Future-like object 5757db96d56Sopenharmony_ci and there is no running event loop. 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ciTimeouts 5797db96d56Sopenharmony_ci======== 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ci.. coroutinefunction:: timeout(delay) 5827db96d56Sopenharmony_ci 5837db96d56Sopenharmony_ci An :ref:`asynchronous context manager <async-context-managers>` 5847db96d56Sopenharmony_ci that can be used to limit the amount of time spent waiting on 5857db96d56Sopenharmony_ci something. 5867db96d56Sopenharmony_ci 5877db96d56Sopenharmony_ci *delay* can either be ``None``, or a float/int number of 5887db96d56Sopenharmony_ci seconds to wait. If *delay* is ``None``, no time limit will 5897db96d56Sopenharmony_ci be applied; this can be useful if the delay is unknown when 5907db96d56Sopenharmony_ci the context manager is created. 5917db96d56Sopenharmony_ci 5927db96d56Sopenharmony_ci In either case, the context manager can be rescheduled after 5937db96d56Sopenharmony_ci creation using :meth:`Timeout.reschedule`. 5947db96d56Sopenharmony_ci 5957db96d56Sopenharmony_ci Example:: 5967db96d56Sopenharmony_ci 5977db96d56Sopenharmony_ci async def main(): 5987db96d56Sopenharmony_ci async with asyncio.timeout(10): 5997db96d56Sopenharmony_ci await long_running_task() 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ci If ``long_running_task`` takes more than 10 seconds to complete, 6027db96d56Sopenharmony_ci the context manager will cancel the current task and handle 6037db96d56Sopenharmony_ci the resulting :exc:`asyncio.CancelledError` internally, transforming it 6047db96d56Sopenharmony_ci into an :exc:`asyncio.TimeoutError` which can be caught and handled. 6057db96d56Sopenharmony_ci 6067db96d56Sopenharmony_ci .. note:: 6077db96d56Sopenharmony_ci 6087db96d56Sopenharmony_ci The :func:`asyncio.timeout` context manager is what transforms 6097db96d56Sopenharmony_ci the :exc:`asyncio.CancelledError` into an :exc:`asyncio.TimeoutError`, 6107db96d56Sopenharmony_ci which means the :exc:`asyncio.TimeoutError` can only be caught 6117db96d56Sopenharmony_ci *outside* of the context manager. 6127db96d56Sopenharmony_ci 6137db96d56Sopenharmony_ci Example of catching :exc:`asyncio.TimeoutError`:: 6147db96d56Sopenharmony_ci 6157db96d56Sopenharmony_ci async def main(): 6167db96d56Sopenharmony_ci try: 6177db96d56Sopenharmony_ci async with asyncio.timeout(10): 6187db96d56Sopenharmony_ci await long_running_task() 6197db96d56Sopenharmony_ci except TimeoutError: 6207db96d56Sopenharmony_ci print("The long operation timed out, but we've handled it.") 6217db96d56Sopenharmony_ci 6227db96d56Sopenharmony_ci print("This statement will run regardless.") 6237db96d56Sopenharmony_ci 6247db96d56Sopenharmony_ci The context manager produced by :func:`asyncio.timeout` can be 6257db96d56Sopenharmony_ci rescheduled to a different deadline and inspected. 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_ci .. class:: Timeout(when) 6287db96d56Sopenharmony_ci 6297db96d56Sopenharmony_ci An :ref:`asynchronous context manager <async-context-managers>` 6307db96d56Sopenharmony_ci for cancelling overdue coroutines. 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_ci ``when`` should be an absolute time at which the context should time out, 6337db96d56Sopenharmony_ci as measured by the event loop's clock: 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_ci - If ``when`` is ``None``, the timeout will never trigger. 6367db96d56Sopenharmony_ci - If ``when < loop.time()``, the timeout will trigger on the next 6377db96d56Sopenharmony_ci iteration of the event loop. 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci .. method:: when() -> float | None 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci Return the current deadline, or ``None`` if the current 6427db96d56Sopenharmony_ci deadline is not set. 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ci .. method:: reschedule(when: float | None) 6457db96d56Sopenharmony_ci 6467db96d56Sopenharmony_ci Reschedule the timeout. 6477db96d56Sopenharmony_ci 6487db96d56Sopenharmony_ci .. method:: expired() -> bool 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci Return whether the context manager has exceeded its deadline 6517db96d56Sopenharmony_ci (expired). 6527db96d56Sopenharmony_ci 6537db96d56Sopenharmony_ci Example:: 6547db96d56Sopenharmony_ci 6557db96d56Sopenharmony_ci async def main(): 6567db96d56Sopenharmony_ci try: 6577db96d56Sopenharmony_ci # We do not know the timeout when starting, so we pass ``None``. 6587db96d56Sopenharmony_ci async with asyncio.timeout(None) as cm: 6597db96d56Sopenharmony_ci # We know the timeout now, so we reschedule it. 6607db96d56Sopenharmony_ci new_deadline = get_running_loop().time() + 10 6617db96d56Sopenharmony_ci cm.reschedule(new_deadline) 6627db96d56Sopenharmony_ci 6637db96d56Sopenharmony_ci await long_running_task() 6647db96d56Sopenharmony_ci except TimeoutError: 6657db96d56Sopenharmony_ci pass 6667db96d56Sopenharmony_ci 6677db96d56Sopenharmony_ci if cm.expired(): 6687db96d56Sopenharmony_ci print("Looks like we haven't finished on time.") 6697db96d56Sopenharmony_ci 6707db96d56Sopenharmony_ci Timeout context managers can be safely nested. 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_ci .. versionadded:: 3.11 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ci.. coroutinefunction:: timeout_at(when) 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ci Similar to :func:`asyncio.timeout`, except *when* is the absolute time 6777db96d56Sopenharmony_ci to stop waiting, or ``None``. 6787db96d56Sopenharmony_ci 6797db96d56Sopenharmony_ci Example:: 6807db96d56Sopenharmony_ci 6817db96d56Sopenharmony_ci async def main(): 6827db96d56Sopenharmony_ci loop = get_running_loop() 6837db96d56Sopenharmony_ci deadline = loop.time() + 20 6847db96d56Sopenharmony_ci try: 6857db96d56Sopenharmony_ci async with asyncio.timeout_at(deadline): 6867db96d56Sopenharmony_ci await long_running_task() 6877db96d56Sopenharmony_ci except TimeoutError: 6887db96d56Sopenharmony_ci print("The long operation timed out, but we've handled it.") 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ci print("This statement will run regardless.") 6917db96d56Sopenharmony_ci 6927db96d56Sopenharmony_ci .. versionadded:: 3.11 6937db96d56Sopenharmony_ci 6947db96d56Sopenharmony_ci.. coroutinefunction:: wait_for(aw, timeout) 6957db96d56Sopenharmony_ci 6967db96d56Sopenharmony_ci Wait for the *aw* :ref:`awaitable <asyncio-awaitables>` 6977db96d56Sopenharmony_ci to complete with a timeout. 6987db96d56Sopenharmony_ci 6997db96d56Sopenharmony_ci If *aw* is a coroutine it is automatically scheduled as a Task. 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci *timeout* can either be ``None`` or a float or int number of seconds 7027db96d56Sopenharmony_ci to wait for. If *timeout* is ``None``, block until the future 7037db96d56Sopenharmony_ci completes. 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci If a timeout occurs, it cancels the task and raises 7067db96d56Sopenharmony_ci :exc:`TimeoutError`. 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_ci To avoid the task :meth:`cancellation <Task.cancel>`, 7097db96d56Sopenharmony_ci wrap it in :func:`shield`. 7107db96d56Sopenharmony_ci 7117db96d56Sopenharmony_ci The function will wait until the future is actually cancelled, 7127db96d56Sopenharmony_ci so the total wait time may exceed the *timeout*. If an exception 7137db96d56Sopenharmony_ci happens during cancellation, it is propagated. 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_ci If the wait is cancelled, the future *aw* is also cancelled. 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_ci .. versionchanged:: 3.10 7187db96d56Sopenharmony_ci Removed the *loop* parameter. 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_ci .. _asyncio_example_waitfor: 7217db96d56Sopenharmony_ci 7227db96d56Sopenharmony_ci Example:: 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci async def eternity(): 7257db96d56Sopenharmony_ci # Sleep for one hour 7267db96d56Sopenharmony_ci await asyncio.sleep(3600) 7277db96d56Sopenharmony_ci print('yay!') 7287db96d56Sopenharmony_ci 7297db96d56Sopenharmony_ci async def main(): 7307db96d56Sopenharmony_ci # Wait for at most 1 second 7317db96d56Sopenharmony_ci try: 7327db96d56Sopenharmony_ci await asyncio.wait_for(eternity(), timeout=1.0) 7337db96d56Sopenharmony_ci except TimeoutError: 7347db96d56Sopenharmony_ci print('timeout!') 7357db96d56Sopenharmony_ci 7367db96d56Sopenharmony_ci asyncio.run(main()) 7377db96d56Sopenharmony_ci 7387db96d56Sopenharmony_ci # Expected output: 7397db96d56Sopenharmony_ci # 7407db96d56Sopenharmony_ci # timeout! 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ci .. versionchanged:: 3.7 7437db96d56Sopenharmony_ci When *aw* is cancelled due to a timeout, ``wait_for`` waits 7447db96d56Sopenharmony_ci for *aw* to be cancelled. Previously, it raised 7457db96d56Sopenharmony_ci :exc:`TimeoutError` immediately. 7467db96d56Sopenharmony_ci 7477db96d56Sopenharmony_ci .. versionchanged:: 3.10 7487db96d56Sopenharmony_ci Removed the *loop* parameter. 7497db96d56Sopenharmony_ci 7507db96d56Sopenharmony_ci 7517db96d56Sopenharmony_ciWaiting Primitives 7527db96d56Sopenharmony_ci================== 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ci.. coroutinefunction:: wait(aws, *, timeout=None, return_when=ALL_COMPLETED) 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci Run :class:`~asyncio.Future` and :class:`~asyncio.Task` instances in the *aws* 7577db96d56Sopenharmony_ci iterable concurrently and block until the condition specified 7587db96d56Sopenharmony_ci by *return_when*. 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_ci The *aws* iterable must not be empty and generators yielding tasks are not accepted. 7617db96d56Sopenharmony_ci 7627db96d56Sopenharmony_ci Returns two sets of Tasks/Futures: ``(done, pending)``. 7637db96d56Sopenharmony_ci 7647db96d56Sopenharmony_ci Usage:: 7657db96d56Sopenharmony_ci 7667db96d56Sopenharmony_ci done, pending = await asyncio.wait(aws) 7677db96d56Sopenharmony_ci 7687db96d56Sopenharmony_ci *timeout* (a float or int), if specified, can be used to control 7697db96d56Sopenharmony_ci the maximum number of seconds to wait before returning. 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_ci Note that this function does not raise :exc:`TimeoutError`. 7727db96d56Sopenharmony_ci Futures or Tasks that aren't done when the timeout occurs are simply 7737db96d56Sopenharmony_ci returned in the second set. 7747db96d56Sopenharmony_ci 7757db96d56Sopenharmony_ci *return_when* indicates when this function should return. It must 7767db96d56Sopenharmony_ci be one of the following constants: 7777db96d56Sopenharmony_ci 7787db96d56Sopenharmony_ci .. tabularcolumns:: |l|L| 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci +-----------------------------+----------------------------------------+ 7817db96d56Sopenharmony_ci | Constant | Description | 7827db96d56Sopenharmony_ci +=============================+========================================+ 7837db96d56Sopenharmony_ci | :const:`FIRST_COMPLETED` | The function will return when any | 7847db96d56Sopenharmony_ci | | future finishes or is cancelled. | 7857db96d56Sopenharmony_ci +-----------------------------+----------------------------------------+ 7867db96d56Sopenharmony_ci | :const:`FIRST_EXCEPTION` | The function will return when any | 7877db96d56Sopenharmony_ci | | future finishes by raising an | 7887db96d56Sopenharmony_ci | | exception. If no future raises an | 7897db96d56Sopenharmony_ci | | exception then it is equivalent to | 7907db96d56Sopenharmony_ci | | :const:`ALL_COMPLETED`. | 7917db96d56Sopenharmony_ci +-----------------------------+----------------------------------------+ 7927db96d56Sopenharmony_ci | :const:`ALL_COMPLETED` | The function will return when all | 7937db96d56Sopenharmony_ci | | futures finish or are cancelled. | 7947db96d56Sopenharmony_ci +-----------------------------+----------------------------------------+ 7957db96d56Sopenharmony_ci 7967db96d56Sopenharmony_ci Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the 7977db96d56Sopenharmony_ci futures when a timeout occurs. 7987db96d56Sopenharmony_ci 7997db96d56Sopenharmony_ci .. versionchanged:: 3.10 8007db96d56Sopenharmony_ci Removed the *loop* parameter. 8017db96d56Sopenharmony_ci 8027db96d56Sopenharmony_ci .. versionchanged:: 3.11 8037db96d56Sopenharmony_ci Passing coroutine objects to ``wait()`` directly is forbidden. 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci.. function:: as_completed(aws, *, timeout=None) 8067db96d56Sopenharmony_ci 8077db96d56Sopenharmony_ci Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws* 8087db96d56Sopenharmony_ci iterable concurrently. Generators yielding tasks are not accepted 8097db96d56Sopenharmony_ci as *aws* iterable. Return an iterator of coroutines. 8107db96d56Sopenharmony_ci Each coroutine returned can be awaited to get the earliest next 8117db96d56Sopenharmony_ci result from the iterable of the remaining awaitables. 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci Raises :exc:`TimeoutError` if the timeout occurs before 8147db96d56Sopenharmony_ci all Futures are done. 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ci Example:: 8177db96d56Sopenharmony_ci 8187db96d56Sopenharmony_ci for coro in as_completed(aws): 8197db96d56Sopenharmony_ci earliest_result = await coro 8207db96d56Sopenharmony_ci # ... 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_ci .. versionchanged:: 3.10 8237db96d56Sopenharmony_ci Removed the *loop* parameter. 8247db96d56Sopenharmony_ci 8257db96d56Sopenharmony_ci .. deprecated:: 3.10 8267db96d56Sopenharmony_ci Deprecation warning is emitted if not all awaitable objects in the *aws* 8277db96d56Sopenharmony_ci iterable are Future-like objects and there is no running event loop. 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ciRunning in Threads 8317db96d56Sopenharmony_ci================== 8327db96d56Sopenharmony_ci 8337db96d56Sopenharmony_ci.. coroutinefunction:: to_thread(func, /, *args, **kwargs) 8347db96d56Sopenharmony_ci 8357db96d56Sopenharmony_ci Asynchronously run function *func* in a separate thread. 8367db96d56Sopenharmony_ci 8377db96d56Sopenharmony_ci Any \*args and \*\*kwargs supplied for this function are directly passed 8387db96d56Sopenharmony_ci to *func*. Also, the current :class:`contextvars.Context` is propagated, 8397db96d56Sopenharmony_ci allowing context variables from the event loop thread to be accessed in the 8407db96d56Sopenharmony_ci separate thread. 8417db96d56Sopenharmony_ci 8427db96d56Sopenharmony_ci Return a coroutine that can be awaited to get the eventual result of *func*. 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci This coroutine function is primarily intended to be used for executing 8457db96d56Sopenharmony_ci IO-bound functions/methods that would otherwise block the event loop if 8467db96d56Sopenharmony_ci they were run in the main thread. For example:: 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_ci def blocking_io(): 8497db96d56Sopenharmony_ci print(f"start blocking_io at {time.strftime('%X')}") 8507db96d56Sopenharmony_ci # Note that time.sleep() can be replaced with any blocking 8517db96d56Sopenharmony_ci # IO-bound operation, such as file operations. 8527db96d56Sopenharmony_ci time.sleep(1) 8537db96d56Sopenharmony_ci print(f"blocking_io complete at {time.strftime('%X')}") 8547db96d56Sopenharmony_ci 8557db96d56Sopenharmony_ci async def main(): 8567db96d56Sopenharmony_ci print(f"started main at {time.strftime('%X')}") 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci await asyncio.gather( 8597db96d56Sopenharmony_ci asyncio.to_thread(blocking_io), 8607db96d56Sopenharmony_ci asyncio.sleep(1)) 8617db96d56Sopenharmony_ci 8627db96d56Sopenharmony_ci print(f"finished main at {time.strftime('%X')}") 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_ci 8657db96d56Sopenharmony_ci asyncio.run(main()) 8667db96d56Sopenharmony_ci 8677db96d56Sopenharmony_ci # Expected output: 8687db96d56Sopenharmony_ci # 8697db96d56Sopenharmony_ci # started main at 19:50:53 8707db96d56Sopenharmony_ci # start blocking_io at 19:50:53 8717db96d56Sopenharmony_ci # blocking_io complete at 19:50:54 8727db96d56Sopenharmony_ci # finished main at 19:50:54 8737db96d56Sopenharmony_ci 8747db96d56Sopenharmony_ci Directly calling ``blocking_io()`` in any coroutine would block the event loop 8757db96d56Sopenharmony_ci for its duration, resulting in an additional 1 second of run time. Instead, 8767db96d56Sopenharmony_ci by using ``asyncio.to_thread()``, we can run it in a separate thread without 8777db96d56Sopenharmony_ci blocking the event loop. 8787db96d56Sopenharmony_ci 8797db96d56Sopenharmony_ci .. note:: 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci Due to the :term:`GIL`, ``asyncio.to_thread()`` can typically only be used 8827db96d56Sopenharmony_ci to make IO-bound functions non-blocking. However, for extension modules 8837db96d56Sopenharmony_ci that release the GIL or alternative Python implementations that don't 8847db96d56Sopenharmony_ci have one, ``asyncio.to_thread()`` can also be used for CPU-bound functions. 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci .. versionadded:: 3.9 8877db96d56Sopenharmony_ci 8887db96d56Sopenharmony_ci 8897db96d56Sopenharmony_ciScheduling From Other Threads 8907db96d56Sopenharmony_ci============================= 8917db96d56Sopenharmony_ci 8927db96d56Sopenharmony_ci.. function:: run_coroutine_threadsafe(coro, loop) 8937db96d56Sopenharmony_ci 8947db96d56Sopenharmony_ci Submit a coroutine to the given event loop. Thread-safe. 8957db96d56Sopenharmony_ci 8967db96d56Sopenharmony_ci Return a :class:`concurrent.futures.Future` to wait for the result 8977db96d56Sopenharmony_ci from another OS thread. 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci This function is meant to be called from a different OS thread 9007db96d56Sopenharmony_ci than the one where the event loop is running. Example:: 9017db96d56Sopenharmony_ci 9027db96d56Sopenharmony_ci # Create a coroutine 9037db96d56Sopenharmony_ci coro = asyncio.sleep(1, result=3) 9047db96d56Sopenharmony_ci 9057db96d56Sopenharmony_ci # Submit the coroutine to a given loop 9067db96d56Sopenharmony_ci future = asyncio.run_coroutine_threadsafe(coro, loop) 9077db96d56Sopenharmony_ci 9087db96d56Sopenharmony_ci # Wait for the result with an optional timeout argument 9097db96d56Sopenharmony_ci assert future.result(timeout) == 3 9107db96d56Sopenharmony_ci 9117db96d56Sopenharmony_ci If an exception is raised in the coroutine, the returned Future 9127db96d56Sopenharmony_ci will be notified. It can also be used to cancel the task in 9137db96d56Sopenharmony_ci the event loop:: 9147db96d56Sopenharmony_ci 9157db96d56Sopenharmony_ci try: 9167db96d56Sopenharmony_ci result = future.result(timeout) 9177db96d56Sopenharmony_ci except TimeoutError: 9187db96d56Sopenharmony_ci print('The coroutine took too long, cancelling the task...') 9197db96d56Sopenharmony_ci future.cancel() 9207db96d56Sopenharmony_ci except Exception as exc: 9217db96d56Sopenharmony_ci print(f'The coroutine raised an exception: {exc!r}') 9227db96d56Sopenharmony_ci else: 9237db96d56Sopenharmony_ci print(f'The coroutine returned: {result!r}') 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_ci See the :ref:`concurrency and multithreading <asyncio-multithreading>` 9267db96d56Sopenharmony_ci section of the documentation. 9277db96d56Sopenharmony_ci 9287db96d56Sopenharmony_ci Unlike other asyncio functions this function requires the *loop* 9297db96d56Sopenharmony_ci argument to be passed explicitly. 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ci .. versionadded:: 3.5.1 9327db96d56Sopenharmony_ci 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_ciIntrospection 9357db96d56Sopenharmony_ci============= 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci 9387db96d56Sopenharmony_ci.. function:: current_task(loop=None) 9397db96d56Sopenharmony_ci 9407db96d56Sopenharmony_ci Return the currently running :class:`Task` instance, or ``None`` if 9417db96d56Sopenharmony_ci no task is running. 9427db96d56Sopenharmony_ci 9437db96d56Sopenharmony_ci If *loop* is ``None`` :func:`get_running_loop` is used to get 9447db96d56Sopenharmony_ci the current loop. 9457db96d56Sopenharmony_ci 9467db96d56Sopenharmony_ci .. versionadded:: 3.7 9477db96d56Sopenharmony_ci 9487db96d56Sopenharmony_ci 9497db96d56Sopenharmony_ci.. function:: all_tasks(loop=None) 9507db96d56Sopenharmony_ci 9517db96d56Sopenharmony_ci Return a set of not yet finished :class:`Task` objects run by 9527db96d56Sopenharmony_ci the loop. 9537db96d56Sopenharmony_ci 9547db96d56Sopenharmony_ci If *loop* is ``None``, :func:`get_running_loop` is used for getting 9557db96d56Sopenharmony_ci current loop. 9567db96d56Sopenharmony_ci 9577db96d56Sopenharmony_ci .. versionadded:: 3.7 9587db96d56Sopenharmony_ci 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_ci.. function:: iscoroutine(obj) 9617db96d56Sopenharmony_ci 9627db96d56Sopenharmony_ci Return ``True`` if *obj* is a coroutine object. 9637db96d56Sopenharmony_ci 9647db96d56Sopenharmony_ci .. versionadded:: 3.4 9657db96d56Sopenharmony_ci 9667db96d56Sopenharmony_ci 9677db96d56Sopenharmony_ciTask Object 9687db96d56Sopenharmony_ci=========== 9697db96d56Sopenharmony_ci 9707db96d56Sopenharmony_ci.. class:: Task(coro, *, loop=None, name=None, context=None) 9717db96d56Sopenharmony_ci 9727db96d56Sopenharmony_ci A :class:`Future-like <Future>` object that runs a Python 9737db96d56Sopenharmony_ci :ref:`coroutine <coroutine>`. Not thread-safe. 9747db96d56Sopenharmony_ci 9757db96d56Sopenharmony_ci Tasks are used to run coroutines in event loops. 9767db96d56Sopenharmony_ci If a coroutine awaits on a Future, the Task suspends 9777db96d56Sopenharmony_ci the execution of the coroutine and waits for the completion 9787db96d56Sopenharmony_ci of the Future. When the Future is *done*, the execution of 9797db96d56Sopenharmony_ci the wrapped coroutine resumes. 9807db96d56Sopenharmony_ci 9817db96d56Sopenharmony_ci Event loops use cooperative scheduling: an event loop runs 9827db96d56Sopenharmony_ci one Task at a time. While a Task awaits for the completion of a 9837db96d56Sopenharmony_ci Future, the event loop runs other Tasks, callbacks, or performs 9847db96d56Sopenharmony_ci IO operations. 9857db96d56Sopenharmony_ci 9867db96d56Sopenharmony_ci Use the high-level :func:`asyncio.create_task` function to create 9877db96d56Sopenharmony_ci Tasks, or the low-level :meth:`loop.create_task` or 9887db96d56Sopenharmony_ci :func:`ensure_future` functions. Manual instantiation of Tasks 9897db96d56Sopenharmony_ci is discouraged. 9907db96d56Sopenharmony_ci 9917db96d56Sopenharmony_ci To cancel a running Task use the :meth:`cancel` method. Calling it 9927db96d56Sopenharmony_ci will cause the Task to throw a :exc:`CancelledError` exception into 9937db96d56Sopenharmony_ci the wrapped coroutine. If a coroutine is awaiting on a Future 9947db96d56Sopenharmony_ci object during cancellation, the Future object will be cancelled. 9957db96d56Sopenharmony_ci 9967db96d56Sopenharmony_ci :meth:`cancelled` can be used to check if the Task was cancelled. 9977db96d56Sopenharmony_ci The method returns ``True`` if the wrapped coroutine did not 9987db96d56Sopenharmony_ci suppress the :exc:`CancelledError` exception and was actually 9997db96d56Sopenharmony_ci cancelled. 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_ci :class:`asyncio.Task` inherits from :class:`Future` all of its 10027db96d56Sopenharmony_ci APIs except :meth:`Future.set_result` and 10037db96d56Sopenharmony_ci :meth:`Future.set_exception`. 10047db96d56Sopenharmony_ci 10057db96d56Sopenharmony_ci An optional keyword-only *context* argument allows specifying a 10067db96d56Sopenharmony_ci custom :class:`contextvars.Context` for the *coro* to run in. 10077db96d56Sopenharmony_ci If no *context* is provided, the Task copies the current context 10087db96d56Sopenharmony_ci and later runs its coroutine in the copied context. 10097db96d56Sopenharmony_ci 10107db96d56Sopenharmony_ci .. versionchanged:: 3.7 10117db96d56Sopenharmony_ci Added support for the :mod:`contextvars` module. 10127db96d56Sopenharmony_ci 10137db96d56Sopenharmony_ci .. versionchanged:: 3.8 10147db96d56Sopenharmony_ci Added the *name* parameter. 10157db96d56Sopenharmony_ci 10167db96d56Sopenharmony_ci .. deprecated:: 3.10 10177db96d56Sopenharmony_ci Deprecation warning is emitted if *loop* is not specified 10187db96d56Sopenharmony_ci and there is no running event loop. 10197db96d56Sopenharmony_ci 10207db96d56Sopenharmony_ci .. versionchanged:: 3.11 10217db96d56Sopenharmony_ci Added the *context* parameter. 10227db96d56Sopenharmony_ci 10237db96d56Sopenharmony_ci .. method:: done() 10247db96d56Sopenharmony_ci 10257db96d56Sopenharmony_ci Return ``True`` if the Task is *done*. 10267db96d56Sopenharmony_ci 10277db96d56Sopenharmony_ci A Task is *done* when the wrapped coroutine either returned 10287db96d56Sopenharmony_ci a value, raised an exception, or the Task was cancelled. 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_ci .. method:: result() 10317db96d56Sopenharmony_ci 10327db96d56Sopenharmony_ci Return the result of the Task. 10337db96d56Sopenharmony_ci 10347db96d56Sopenharmony_ci If the Task is *done*, the result of the wrapped coroutine 10357db96d56Sopenharmony_ci is returned (or if the coroutine raised an exception, that 10367db96d56Sopenharmony_ci exception is re-raised.) 10377db96d56Sopenharmony_ci 10387db96d56Sopenharmony_ci If the Task has been *cancelled*, this method raises 10397db96d56Sopenharmony_ci a :exc:`CancelledError` exception. 10407db96d56Sopenharmony_ci 10417db96d56Sopenharmony_ci If the Task's result isn't yet available, this method raises 10427db96d56Sopenharmony_ci a :exc:`InvalidStateError` exception. 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_ci .. method:: exception() 10457db96d56Sopenharmony_ci 10467db96d56Sopenharmony_ci Return the exception of the Task. 10477db96d56Sopenharmony_ci 10487db96d56Sopenharmony_ci If the wrapped coroutine raised an exception that exception 10497db96d56Sopenharmony_ci is returned. If the wrapped coroutine returned normally 10507db96d56Sopenharmony_ci this method returns ``None``. 10517db96d56Sopenharmony_ci 10527db96d56Sopenharmony_ci If the Task has been *cancelled*, this method raises a 10537db96d56Sopenharmony_ci :exc:`CancelledError` exception. 10547db96d56Sopenharmony_ci 10557db96d56Sopenharmony_ci If the Task isn't *done* yet, this method raises an 10567db96d56Sopenharmony_ci :exc:`InvalidStateError` exception. 10577db96d56Sopenharmony_ci 10587db96d56Sopenharmony_ci .. method:: add_done_callback(callback, *, context=None) 10597db96d56Sopenharmony_ci 10607db96d56Sopenharmony_ci Add a callback to be run when the Task is *done*. 10617db96d56Sopenharmony_ci 10627db96d56Sopenharmony_ci This method should only be used in low-level callback-based code. 10637db96d56Sopenharmony_ci 10647db96d56Sopenharmony_ci See the documentation of :meth:`Future.add_done_callback` 10657db96d56Sopenharmony_ci for more details. 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci .. method:: remove_done_callback(callback) 10687db96d56Sopenharmony_ci 10697db96d56Sopenharmony_ci Remove *callback* from the callbacks list. 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci This method should only be used in low-level callback-based code. 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_ci See the documentation of :meth:`Future.remove_done_callback` 10747db96d56Sopenharmony_ci for more details. 10757db96d56Sopenharmony_ci 10767db96d56Sopenharmony_ci .. method:: get_stack(*, limit=None) 10777db96d56Sopenharmony_ci 10787db96d56Sopenharmony_ci Return the list of stack frames for this Task. 10797db96d56Sopenharmony_ci 10807db96d56Sopenharmony_ci If the wrapped coroutine is not done, this returns the stack 10817db96d56Sopenharmony_ci where it is suspended. If the coroutine has completed 10827db96d56Sopenharmony_ci successfully or was cancelled, this returns an empty list. 10837db96d56Sopenharmony_ci If the coroutine was terminated by an exception, this returns 10847db96d56Sopenharmony_ci the list of traceback frames. 10857db96d56Sopenharmony_ci 10867db96d56Sopenharmony_ci The frames are always ordered from oldest to newest. 10877db96d56Sopenharmony_ci 10887db96d56Sopenharmony_ci Only one stack frame is returned for a suspended coroutine. 10897db96d56Sopenharmony_ci 10907db96d56Sopenharmony_ci The optional *limit* argument sets the maximum number of frames 10917db96d56Sopenharmony_ci to return; by default all available frames are returned. 10927db96d56Sopenharmony_ci The ordering of the returned list differs depending on whether 10937db96d56Sopenharmony_ci a stack or a traceback is returned: the newest frames of a 10947db96d56Sopenharmony_ci stack are returned, but the oldest frames of a traceback are 10957db96d56Sopenharmony_ci returned. (This matches the behavior of the traceback module.) 10967db96d56Sopenharmony_ci 10977db96d56Sopenharmony_ci .. method:: print_stack(*, limit=None, file=None) 10987db96d56Sopenharmony_ci 10997db96d56Sopenharmony_ci Print the stack or traceback for this Task. 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_ci This produces output similar to that of the traceback module 11027db96d56Sopenharmony_ci for the frames retrieved by :meth:`get_stack`. 11037db96d56Sopenharmony_ci 11047db96d56Sopenharmony_ci The *limit* argument is passed to :meth:`get_stack` directly. 11057db96d56Sopenharmony_ci 11067db96d56Sopenharmony_ci The *file* argument is an I/O stream to which the output 11077db96d56Sopenharmony_ci is written; by default output is written to :data:`sys.stdout`. 11087db96d56Sopenharmony_ci 11097db96d56Sopenharmony_ci .. method:: get_coro() 11107db96d56Sopenharmony_ci 11117db96d56Sopenharmony_ci Return the coroutine object wrapped by the :class:`Task`. 11127db96d56Sopenharmony_ci 11137db96d56Sopenharmony_ci .. versionadded:: 3.8 11147db96d56Sopenharmony_ci 11157db96d56Sopenharmony_ci .. method:: get_name() 11167db96d56Sopenharmony_ci 11177db96d56Sopenharmony_ci Return the name of the Task. 11187db96d56Sopenharmony_ci 11197db96d56Sopenharmony_ci If no name has been explicitly assigned to the Task, the default 11207db96d56Sopenharmony_ci asyncio Task implementation generates a default name during 11217db96d56Sopenharmony_ci instantiation. 11227db96d56Sopenharmony_ci 11237db96d56Sopenharmony_ci .. versionadded:: 3.8 11247db96d56Sopenharmony_ci 11257db96d56Sopenharmony_ci .. method:: set_name(value) 11267db96d56Sopenharmony_ci 11277db96d56Sopenharmony_ci Set the name of the Task. 11287db96d56Sopenharmony_ci 11297db96d56Sopenharmony_ci The *value* argument can be any object, which is then 11307db96d56Sopenharmony_ci converted to a string. 11317db96d56Sopenharmony_ci 11327db96d56Sopenharmony_ci In the default Task implementation, the name will be visible 11337db96d56Sopenharmony_ci in the :func:`repr` output of a task object. 11347db96d56Sopenharmony_ci 11357db96d56Sopenharmony_ci .. versionadded:: 3.8 11367db96d56Sopenharmony_ci 11377db96d56Sopenharmony_ci .. method:: cancel(msg=None) 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ci Request the Task to be cancelled. 11407db96d56Sopenharmony_ci 11417db96d56Sopenharmony_ci This arranges for a :exc:`CancelledError` exception to be thrown 11427db96d56Sopenharmony_ci into the wrapped coroutine on the next cycle of the event loop. 11437db96d56Sopenharmony_ci 11447db96d56Sopenharmony_ci The coroutine then has a chance to clean up or even deny the 11457db96d56Sopenharmony_ci request by suppressing the exception with a :keyword:`try` ... 11467db96d56Sopenharmony_ci ... ``except CancelledError`` ... :keyword:`finally` block. 11477db96d56Sopenharmony_ci Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does 11487db96d56Sopenharmony_ci not guarantee that the Task will be cancelled, although 11497db96d56Sopenharmony_ci suppressing cancellation completely is not common and is actively 11507db96d56Sopenharmony_ci discouraged. Should the coroutine nevertheless decide to suppress 11517db96d56Sopenharmony_ci the cancellation, it needs to call :meth:`Task.uncancel` in addition 11527db96d56Sopenharmony_ci to catching the exception. 11537db96d56Sopenharmony_ci 11547db96d56Sopenharmony_ci .. versionchanged:: 3.9 11557db96d56Sopenharmony_ci Added the *msg* parameter. 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ci .. versionchanged:: 3.11 11587db96d56Sopenharmony_ci The ``msg`` parameter is propagated from cancelled task to its awaiter. 11597db96d56Sopenharmony_ci 11607db96d56Sopenharmony_ci .. _asyncio_example_task_cancel: 11617db96d56Sopenharmony_ci 11627db96d56Sopenharmony_ci The following example illustrates how coroutines can intercept 11637db96d56Sopenharmony_ci the cancellation request:: 11647db96d56Sopenharmony_ci 11657db96d56Sopenharmony_ci async def cancel_me(): 11667db96d56Sopenharmony_ci print('cancel_me(): before sleep') 11677db96d56Sopenharmony_ci 11687db96d56Sopenharmony_ci try: 11697db96d56Sopenharmony_ci # Wait for 1 hour 11707db96d56Sopenharmony_ci await asyncio.sleep(3600) 11717db96d56Sopenharmony_ci except asyncio.CancelledError: 11727db96d56Sopenharmony_ci print('cancel_me(): cancel sleep') 11737db96d56Sopenharmony_ci raise 11747db96d56Sopenharmony_ci finally: 11757db96d56Sopenharmony_ci print('cancel_me(): after sleep') 11767db96d56Sopenharmony_ci 11777db96d56Sopenharmony_ci async def main(): 11787db96d56Sopenharmony_ci # Create a "cancel_me" Task 11797db96d56Sopenharmony_ci task = asyncio.create_task(cancel_me()) 11807db96d56Sopenharmony_ci 11817db96d56Sopenharmony_ci # Wait for 1 second 11827db96d56Sopenharmony_ci await asyncio.sleep(1) 11837db96d56Sopenharmony_ci 11847db96d56Sopenharmony_ci task.cancel() 11857db96d56Sopenharmony_ci try: 11867db96d56Sopenharmony_ci await task 11877db96d56Sopenharmony_ci except asyncio.CancelledError: 11887db96d56Sopenharmony_ci print("main(): cancel_me is cancelled now") 11897db96d56Sopenharmony_ci 11907db96d56Sopenharmony_ci asyncio.run(main()) 11917db96d56Sopenharmony_ci 11927db96d56Sopenharmony_ci # Expected output: 11937db96d56Sopenharmony_ci # 11947db96d56Sopenharmony_ci # cancel_me(): before sleep 11957db96d56Sopenharmony_ci # cancel_me(): cancel sleep 11967db96d56Sopenharmony_ci # cancel_me(): after sleep 11977db96d56Sopenharmony_ci # main(): cancel_me is cancelled now 11987db96d56Sopenharmony_ci 11997db96d56Sopenharmony_ci .. method:: cancelled() 12007db96d56Sopenharmony_ci 12017db96d56Sopenharmony_ci Return ``True`` if the Task is *cancelled*. 12027db96d56Sopenharmony_ci 12037db96d56Sopenharmony_ci The Task is *cancelled* when the cancellation was requested with 12047db96d56Sopenharmony_ci :meth:`cancel` and the wrapped coroutine propagated the 12057db96d56Sopenharmony_ci :exc:`CancelledError` exception thrown into it. 12067db96d56Sopenharmony_ci 12077db96d56Sopenharmony_ci .. method:: uncancel() 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_ci Decrement the count of cancellation requests to this Task. 12107db96d56Sopenharmony_ci 12117db96d56Sopenharmony_ci Returns the remaining number of cancellation requests. 12127db96d56Sopenharmony_ci 12137db96d56Sopenharmony_ci Note that once execution of a cancelled task completed, further 12147db96d56Sopenharmony_ci calls to :meth:`uncancel` are ineffective. 12157db96d56Sopenharmony_ci 12167db96d56Sopenharmony_ci .. versionadded:: 3.11 12177db96d56Sopenharmony_ci 12187db96d56Sopenharmony_ci This method is used by asyncio's internals and isn't expected to be 12197db96d56Sopenharmony_ci used by end-user code. In particular, if a Task gets successfully 12207db96d56Sopenharmony_ci uncancelled, this allows for elements of structured concurrency like 12217db96d56Sopenharmony_ci :ref:`taskgroups` and :func:`asyncio.timeout` to continue running, 12227db96d56Sopenharmony_ci isolating cancellation to the respective structured block. 12237db96d56Sopenharmony_ci For example:: 12247db96d56Sopenharmony_ci 12257db96d56Sopenharmony_ci async def make_request_with_timeout(): 12267db96d56Sopenharmony_ci try: 12277db96d56Sopenharmony_ci async with asyncio.timeout(1): 12287db96d56Sopenharmony_ci # Structured block affected by the timeout: 12297db96d56Sopenharmony_ci await make_request() 12307db96d56Sopenharmony_ci await make_another_request() 12317db96d56Sopenharmony_ci except TimeoutError: 12327db96d56Sopenharmony_ci log("There was a timeout") 12337db96d56Sopenharmony_ci # Outer code not affected by the timeout: 12347db96d56Sopenharmony_ci await unrelated_code() 12357db96d56Sopenharmony_ci 12367db96d56Sopenharmony_ci While the block with ``make_request()`` and ``make_another_request()`` 12377db96d56Sopenharmony_ci might get cancelled due to the timeout, ``unrelated_code()`` should 12387db96d56Sopenharmony_ci continue running even in case of the timeout. This is implemented 12397db96d56Sopenharmony_ci with :meth:`uncancel`. :class:`TaskGroup` context managers use 12407db96d56Sopenharmony_ci :func:`uncancel` in a similar fashion. 12417db96d56Sopenharmony_ci 12427db96d56Sopenharmony_ci If end-user code is, for some reason, suppresing cancellation by 12437db96d56Sopenharmony_ci catching :exc:`CancelledError`, it needs to call this method to remove 12447db96d56Sopenharmony_ci the cancellation state. 12457db96d56Sopenharmony_ci 12467db96d56Sopenharmony_ci .. method:: cancelling() 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci Return the number of pending cancellation requests to this Task, i.e., 12497db96d56Sopenharmony_ci the number of calls to :meth:`cancel` less the number of 12507db96d56Sopenharmony_ci :meth:`uncancel` calls. 12517db96d56Sopenharmony_ci 12527db96d56Sopenharmony_ci Note that if this number is greater than zero but the Task is 12537db96d56Sopenharmony_ci still executing, :meth:`cancelled` will still return ``False``. 12547db96d56Sopenharmony_ci This is because this number can be lowered by calling :meth:`uncancel`, 12557db96d56Sopenharmony_ci which can lead to the task not being cancelled after all if the 12567db96d56Sopenharmony_ci cancellation requests go down to zero. 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ci This method is used by asyncio's internals and isn't expected to be 12597db96d56Sopenharmony_ci used by end-user code. See :meth:`uncancel` for more details. 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci .. versionadded:: 3.11 1262