mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 e89993cff4
			
		
	
	
		e89993cff4
		
			
		
	
	
	
	
		
			
			The issue being resolved is shown in the 3.10 docs (if you select docs for older versions you won't see a visual glitch).
The newer sphinx version that produces the 3.10 docs doesn't treat the backslash to escape things in some situations it previously did..
(cherry picked from commit dcc997cd28)
Co-authored-by: Andre Delfino <adelfino@gmail.com>
		
	
			
		
			
				
	
	
		
			1028 lines
		
	
	
	
		
			30 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			1028 lines
		
	
	
	
		
			30 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. currentmodule:: asyncio
 | |
| 
 | |
| 
 | |
| ====================
 | |
| Coroutines and Tasks
 | |
| ====================
 | |
| 
 | |
| This section outlines high-level asyncio APIs to work with coroutines
 | |
| and Tasks.
 | |
| 
 | |
| .. contents::
 | |
|    :depth: 1
 | |
|    :local:
 | |
| 
 | |
| 
 | |
| .. _coroutine:
 | |
| 
 | |
| Coroutines
 | |
| ==========
 | |
| 
 | |
| :term:`Coroutines <coroutine>` declared with the async/await syntax is the
 | |
| preferred way of writing asyncio applications.  For example, the following
 | |
| snippet of code (requires Python 3.7+) prints "hello", waits 1 second,
 | |
| and then prints "world"::
 | |
| 
 | |
|     >>> import asyncio
 | |
| 
 | |
|     >>> async def main():
 | |
|     ...     print('hello')
 | |
|     ...     await asyncio.sleep(1)
 | |
|     ...     print('world')
 | |
| 
 | |
|     >>> asyncio.run(main())
 | |
|     hello
 | |
|     world
 | |
| 
 | |
| Note that simply calling a coroutine will not schedule it to
 | |
| be executed::
 | |
| 
 | |
|     >>> main()
 | |
|     <coroutine object main at 0x1053bb7c8>
 | |
| 
 | |
| To actually run a coroutine, asyncio provides three main mechanisms:
 | |
| 
 | |
| * The :func:`asyncio.run` function to run the top-level
 | |
|   entry point "main()" function (see the above example.)
 | |
| 
 | |
| * Awaiting on a coroutine.  The following snippet of code will
 | |
|   print "hello" after waiting for 1 second, and then print "world"
 | |
|   after waiting for *another* 2 seconds::
 | |
| 
 | |
|       import asyncio
 | |
|       import time
 | |
| 
 | |
|       async def say_after(delay, what):
 | |
|           await asyncio.sleep(delay)
 | |
|           print(what)
 | |
| 
 | |
|       async def main():
 | |
|           print(f"started at {time.strftime('%X')}")
 | |
| 
 | |
|           await say_after(1, 'hello')
 | |
|           await say_after(2, 'world')
 | |
| 
 | |
|           print(f"finished at {time.strftime('%X')}")
 | |
| 
 | |
|       asyncio.run(main())
 | |
| 
 | |
|   Expected output::
 | |
| 
 | |
|       started at 17:13:52
 | |
|       hello
 | |
|       world
 | |
|       finished at 17:13:55
 | |
| 
 | |
| * The :func:`asyncio.create_task` function to run coroutines
 | |
|   concurrently as asyncio :class:`Tasks <Task>`.
 | |
| 
 | |
|   Let's modify the above example and run two ``say_after`` coroutines
 | |
|   *concurrently*::
 | |
| 
 | |
|       async def main():
 | |
|           task1 = asyncio.create_task(
 | |
|               say_after(1, 'hello'))
 | |
| 
 | |
|           task2 = asyncio.create_task(
 | |
|               say_after(2, 'world'))
 | |
| 
 | |
|           print(f"started at {time.strftime('%X')}")
 | |
| 
 | |
|           # Wait until both tasks are completed (should take
 | |
|           # around 2 seconds.)
 | |
|           await task1
 | |
|           await task2
 | |
| 
 | |
|           print(f"finished at {time.strftime('%X')}")
 | |
| 
 | |
|   Note that expected output now shows that the snippet runs
 | |
|   1 second faster than before::
 | |
| 
 | |
|       started at 17:14:32
 | |
|       hello
 | |
|       world
 | |
|       finished at 17:14:34
 | |
| 
 | |
| 
 | |
| .. _asyncio-awaitables:
 | |
| 
 | |
| Awaitables
 | |
| ==========
 | |
| 
 | |
| We say that an object is an **awaitable** object if it can be used
 | |
| in an :keyword:`await` expression.  Many asyncio APIs are designed to
 | |
| accept awaitables.
 | |
| 
 | |
| There are three main types of *awaitable* objects:
 | |
| **coroutines**, **Tasks**, and **Futures**.
 | |
| 
 | |
| 
 | |
| .. rubric:: Coroutines
 | |
| 
 | |
| Python coroutines are *awaitables* and therefore can be awaited from
 | |
| other coroutines::
 | |
| 
 | |
|     import asyncio
 | |
| 
 | |
|     async def nested():
 | |
|         return 42
 | |
| 
 | |
|     async def main():
 | |
|         # Nothing happens if we just call "nested()".
 | |
|         # A coroutine object is created but not awaited,
 | |
|         # so it *won't run at all*.
 | |
|         nested()
 | |
| 
 | |
|         # Let's do it differently now and await it:
 | |
|         print(await nested())  # will print "42".
 | |
| 
 | |
|     asyncio.run(main())
 | |
| 
 | |
| .. important::
 | |
| 
 | |
|    In this documentation the term "coroutine" can be used for
 | |
|    two closely related concepts:
 | |
| 
 | |
|    * a *coroutine function*: an :keyword:`async def` function;
 | |
| 
 | |
|    * a *coroutine object*: an object returned by calling a
 | |
|      *coroutine function*.
 | |
| 
 | |
| asyncio also supports legacy :ref:`generator-based
 | |
| <asyncio_generator_based_coro>` coroutines.
 | |
| 
 | |
| 
 | |
| .. rubric:: Tasks
 | |
| 
 | |
| *Tasks* are used to schedule coroutines *concurrently*.
 | |
| 
 | |
| When a coroutine is wrapped into a *Task* with functions like
 | |
| :func:`asyncio.create_task` the coroutine is automatically
 | |
| scheduled to run soon::
 | |
| 
 | |
|     import asyncio
 | |
| 
 | |
|     async def nested():
 | |
|         return 42
 | |
| 
 | |
|     async def main():
 | |
|         # Schedule nested() to run soon concurrently
 | |
|         # with "main()".
 | |
|         task = asyncio.create_task(nested())
 | |
| 
 | |
|         # "task" can now be used to cancel "nested()", or
 | |
|         # can simply be awaited to wait until it is complete:
 | |
|         await task
 | |
| 
 | |
|     asyncio.run(main())
 | |
| 
 | |
| 
 | |
| .. rubric:: Futures
 | |
| 
 | |
| A :class:`Future` is a special **low-level** awaitable object that
 | |
| represents an **eventual result** of an asynchronous operation.
 | |
| 
 | |
| When a Future object is *awaited* it means that the coroutine will
 | |
| wait until the Future is resolved in some other place.
 | |
| 
 | |
| Future objects in asyncio are needed to allow callback-based code
 | |
| to be used with async/await.
 | |
| 
 | |
| Normally **there is no need** to create Future objects at the
 | |
| application level code.
 | |
| 
 | |
| Future objects, sometimes exposed by libraries and some asyncio
 | |
| APIs, can be awaited::
 | |
| 
 | |
|     async def main():
 | |
|         await function_that_returns_a_future_object()
 | |
| 
 | |
|         # this is also valid:
 | |
|         await asyncio.gather(
 | |
|             function_that_returns_a_future_object(),
 | |
|             some_python_coroutine()
 | |
|         )
 | |
| 
 | |
| A good example of a low-level function that returns a Future object
 | |
| is :meth:`loop.run_in_executor`.
 | |
| 
 | |
| 
 | |
| Running an asyncio Program
 | |
| ==========================
 | |
| 
 | |
| .. function:: run(coro, *, debug=False)
 | |
| 
 | |
|     Execute the :term:`coroutine` *coro* and return the result.
 | |
| 
 | |
|     This function runs the passed coroutine, taking care of
 | |
|     managing the asyncio event loop, *finalizing asynchronous
 | |
|     generators*, and closing the threadpool.
 | |
| 
 | |
|     This function cannot be called when another asyncio event loop is
 | |
|     running in the same thread.
 | |
| 
 | |
|     If *debug* is ``True``, the event loop will be run in debug mode.
 | |
| 
 | |
|     This function always creates a new event loop and closes it at
 | |
|     the end.  It should be used as a main entry point for asyncio
 | |
|     programs, and should ideally only be called once.
 | |
| 
 | |
|     Example::
 | |
| 
 | |
|         async def main():
 | |
|             await asyncio.sleep(1)
 | |
|             print('hello')
 | |
| 
 | |
|         asyncio.run(main())
 | |
| 
 | |
|     .. versionadded:: 3.7
 | |
| 
 | |
|     .. versionchanged:: 3.9
 | |
|        Updated to use :meth:`loop.shutdown_default_executor`.
 | |
| 
 | |
|     .. note::
 | |
|        The source code for ``asyncio.run()`` can be found in
 | |
|        :source:`Lib/asyncio/runners.py`.
 | |
| 
 | |
| Creating Tasks
 | |
| ==============
 | |
| 
 | |
| .. function:: create_task(coro, *, name=None)
 | |
| 
 | |
|    Wrap the *coro* :ref:`coroutine <coroutine>` into a :class:`Task`
 | |
|    and schedule its execution.  Return the Task object.
 | |
| 
 | |
|    If *name* is not ``None``, it is set as the name of the task using
 | |
|    :meth:`Task.set_name`.
 | |
| 
 | |
|    The task is executed in the loop returned by :func:`get_running_loop`,
 | |
|    :exc:`RuntimeError` is raised if there is no running loop in
 | |
|    current thread.
 | |
| 
 | |
|    This function has been **added in Python 3.7**.  Prior to
 | |
|    Python 3.7, the low-level :func:`asyncio.ensure_future` function
 | |
|    can be used instead::
 | |
| 
 | |
|        async def coro():
 | |
|            ...
 | |
| 
 | |
|        # In Python 3.7+
 | |
|        task = asyncio.create_task(coro())
 | |
|        ...
 | |
| 
 | |
|        # This works in all Python versions but is less readable
 | |
|        task = asyncio.ensure_future(coro())
 | |
|        ...
 | |
| 
 | |
|    .. versionadded:: 3.7
 | |
| 
 | |
|    .. versionchanged:: 3.8
 | |
|       Added the ``name`` parameter.
 | |
| 
 | |
| 
 | |
| Sleeping
 | |
| ========
 | |
| 
 | |
| .. coroutinefunction:: sleep(delay, result=None, *, loop=None)
 | |
| 
 | |
|    Block for *delay* seconds.
 | |
| 
 | |
|    If *result* is provided, it is returned to the caller
 | |
|    when the coroutine completes.
 | |
| 
 | |
|    ``sleep()`` always suspends the current task, allowing other tasks
 | |
|    to run.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    .. _asyncio_example_sleep:
 | |
| 
 | |
|    Example of coroutine displaying the current date every second
 | |
|    for 5 seconds::
 | |
| 
 | |
|     import asyncio
 | |
|     import datetime
 | |
| 
 | |
|     async def display_date():
 | |
|         loop = asyncio.get_running_loop()
 | |
|         end_time = loop.time() + 5.0
 | |
|         while True:
 | |
|             print(datetime.datetime.now())
 | |
|             if (loop.time() + 1.0) >= end_time:
 | |
|                 break
 | |
|             await asyncio.sleep(1)
 | |
| 
 | |
|     asyncio.run(display_date())
 | |
| 
 | |
| 
 | |
| Running Tasks Concurrently
 | |
| ==========================
 | |
| 
 | |
| .. awaitablefunction:: gather(*aws, loop=None, return_exceptions=False)
 | |
| 
 | |
|    Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 | |
|    sequence *concurrently*.
 | |
| 
 | |
|    If any awaitable in *aws* is a coroutine, it is automatically
 | |
|    scheduled as a Task.
 | |
| 
 | |
|    If all awaitables are completed successfully, the result is an
 | |
|    aggregate list of returned values.  The order of result values
 | |
|    corresponds to the order of awaitables in *aws*.
 | |
| 
 | |
|    If *return_exceptions* is ``False`` (default), the first
 | |
|    raised exception is immediately propagated to the task that
 | |
|    awaits on ``gather()``.  Other awaitables in the *aws* sequence
 | |
|    **won't be cancelled** and will continue to run.
 | |
| 
 | |
|    If *return_exceptions* is ``True``, exceptions are treated the
 | |
|    same as successful results, and aggregated in the result list.
 | |
| 
 | |
|    If ``gather()`` is *cancelled*, all submitted awaitables
 | |
|    (that have not completed yet) are also *cancelled*.
 | |
| 
 | |
|    If any Task or Future from the *aws* sequence is *cancelled*, it is
 | |
|    treated as if it raised :exc:`CancelledError` -- the ``gather()``
 | |
|    call is **not** cancelled in this case.  This is to prevent the
 | |
|    cancellation of one submitted Task/Future to cause other
 | |
|    Tasks/Futures to be cancelled.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    .. _asyncio_example_gather:
 | |
| 
 | |
|    Example::
 | |
| 
 | |
|       import asyncio
 | |
| 
 | |
|       async def factorial(name, number):
 | |
|           f = 1
 | |
|           for i in range(2, number + 1):
 | |
|               print(f"Task {name}: Compute factorial({i})...")
 | |
|               await asyncio.sleep(1)
 | |
|               f *= i
 | |
|           print(f"Task {name}: factorial({number}) = {f}")
 | |
| 
 | |
|       async def main():
 | |
|           # Schedule three calls *concurrently*:
 | |
|           await asyncio.gather(
 | |
|               factorial("A", 2),
 | |
|               factorial("B", 3),
 | |
|               factorial("C", 4),
 | |
|           )
 | |
| 
 | |
|       asyncio.run(main())
 | |
| 
 | |
|       # Expected output:
 | |
|       #
 | |
|       #     Task A: Compute factorial(2)...
 | |
|       #     Task B: Compute factorial(2)...
 | |
|       #     Task C: Compute factorial(2)...
 | |
|       #     Task A: factorial(2) = 2
 | |
|       #     Task B: Compute factorial(3)...
 | |
|       #     Task C: Compute factorial(3)...
 | |
|       #     Task B: factorial(3) = 6
 | |
|       #     Task C: Compute factorial(4)...
 | |
|       #     Task C: factorial(4) = 24
 | |
| 
 | |
|    .. note::
 | |
|       If *return_exceptions* is False, cancelling gather() after it
 | |
|       has been marked done won't cancel any submitted awaitables.
 | |
|       For instance, gather can be marked done after propagating an
 | |
|       exception to the caller, therefore, calling ``gather.cancel()``
 | |
|       after catching an exception (raised by one of the awaitables) from
 | |
|       gather won't cancel any other awaitables.
 | |
| 
 | |
|    .. versionchanged:: 3.7
 | |
|       If the *gather* itself is cancelled, the cancellation is
 | |
|       propagated regardless of *return_exceptions*.
 | |
| 
 | |
| 
 | |
| Shielding From Cancellation
 | |
| ===========================
 | |
| 
 | |
| .. awaitablefunction:: shield(aw, *, loop=None)
 | |
| 
 | |
|    Protect an :ref:`awaitable object <asyncio-awaitables>`
 | |
|    from being :meth:`cancelled <Task.cancel>`.
 | |
| 
 | |
|    If *aw* is a coroutine it is automatically scheduled as a Task.
 | |
| 
 | |
|    The statement::
 | |
| 
 | |
|        res = await shield(something())
 | |
| 
 | |
|    is equivalent to::
 | |
| 
 | |
|        res = await something()
 | |
| 
 | |
|    *except* that if the coroutine containing it is cancelled, the
 | |
|    Task running in ``something()`` is not cancelled.  From the point
 | |
|    of view of ``something()``, the cancellation did not happen.
 | |
|    Although its caller is still cancelled, so the "await" expression
 | |
|    still raises a :exc:`CancelledError`.
 | |
| 
 | |
|    If ``something()`` is cancelled by other means (i.e. from within
 | |
|    itself) that would also cancel ``shield()``.
 | |
| 
 | |
|    If it is desired to completely ignore cancellation (not recommended)
 | |
|    the ``shield()`` function should be combined with a try/except
 | |
|    clause, as follows::
 | |
| 
 | |
|        try:
 | |
|            res = await shield(something())
 | |
|        except CancelledError:
 | |
|            res = None
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
| 
 | |
| Timeouts
 | |
| ========
 | |
| 
 | |
| .. coroutinefunction:: wait_for(aw, timeout, *, loop=None)
 | |
| 
 | |
|    Wait for the *aw* :ref:`awaitable <asyncio-awaitables>`
 | |
|    to complete with a timeout.
 | |
| 
 | |
|    If *aw* is a coroutine it is automatically scheduled as a Task.
 | |
| 
 | |
|    *timeout* can either be ``None`` or a float or int number of seconds
 | |
|    to wait for.  If *timeout* is ``None``, block until the future
 | |
|    completes.
 | |
| 
 | |
|    If a timeout occurs, it cancels the task and raises
 | |
|    :exc:`asyncio.TimeoutError`.
 | |
| 
 | |
|    To avoid the task :meth:`cancellation <Task.cancel>`,
 | |
|    wrap it in :func:`shield`.
 | |
| 
 | |
|    The function will wait until the future is actually cancelled,
 | |
|    so the total wait time may exceed the *timeout*. If an exception
 | |
|    happens during cancellation, it is propagated.
 | |
| 
 | |
|    If the wait is cancelled, the future *aw* is also cancelled.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    .. _asyncio_example_waitfor:
 | |
| 
 | |
|    Example::
 | |
| 
 | |
|        async def eternity():
 | |
|            # Sleep for one hour
 | |
|            await asyncio.sleep(3600)
 | |
|            print('yay!')
 | |
| 
 | |
|        async def main():
 | |
|            # Wait for at most 1 second
 | |
|            try:
 | |
|                await asyncio.wait_for(eternity(), timeout=1.0)
 | |
|            except asyncio.TimeoutError:
 | |
|                print('timeout!')
 | |
| 
 | |
|        asyncio.run(main())
 | |
| 
 | |
|        # Expected output:
 | |
|        #
 | |
|        #     timeout!
 | |
| 
 | |
|    .. versionchanged:: 3.7
 | |
|       When *aw* is cancelled due to a timeout, ``wait_for`` waits
 | |
|       for *aw* to be cancelled.  Previously, it raised
 | |
|       :exc:`asyncio.TimeoutError` immediately.
 | |
| 
 | |
| 
 | |
| Waiting Primitives
 | |
| ==================
 | |
| 
 | |
| .. coroutinefunction:: wait(aws, *, loop=None, timeout=None,\
 | |
|                             return_when=ALL_COMPLETED)
 | |
| 
 | |
|    Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 | |
|    iterable concurrently and block until the condition specified
 | |
|    by *return_when*.
 | |
| 
 | |
|    The *aws* iterable must not be empty.
 | |
| 
 | |
|    Returns two sets of Tasks/Futures: ``(done, pending)``.
 | |
| 
 | |
|    Usage::
 | |
| 
 | |
|         done, pending = await asyncio.wait(aws)
 | |
| 
 | |
|    *timeout* (a float or int), if specified, can be used to control
 | |
|    the maximum number of seconds to wait before returning.
 | |
| 
 | |
|    Note that this function does not raise :exc:`asyncio.TimeoutError`.
 | |
|    Futures or Tasks that aren't done when the timeout occurs are simply
 | |
|    returned in the second set.
 | |
| 
 | |
|    *return_when* indicates when this function should return.  It must
 | |
|    be one of the following constants:
 | |
| 
 | |
|    .. tabularcolumns:: |l|L|
 | |
| 
 | |
|    +-----------------------------+----------------------------------------+
 | |
|    | Constant                    | Description                            |
 | |
|    +=============================+========================================+
 | |
|    | :const:`FIRST_COMPLETED`    | The function will return when any      |
 | |
|    |                             | future finishes or is cancelled.       |
 | |
|    +-----------------------------+----------------------------------------+
 | |
|    | :const:`FIRST_EXCEPTION`    | The function will return when any      |
 | |
|    |                             | future finishes by raising an          |
 | |
|    |                             | exception.  If no future raises an     |
 | |
|    |                             | exception then it is equivalent to     |
 | |
|    |                             | :const:`ALL_COMPLETED`.                |
 | |
|    +-----------------------------+----------------------------------------+
 | |
|    | :const:`ALL_COMPLETED`      | The function will return when all      |
 | |
|    |                             | futures finish or are cancelled.       |
 | |
|    +-----------------------------+----------------------------------------+
 | |
| 
 | |
|    Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the
 | |
|    futures when a timeout occurs.
 | |
| 
 | |
|    .. deprecated:: 3.8
 | |
| 
 | |
|       If any awaitable in *aws* is a coroutine, it is automatically
 | |
|       scheduled as a Task.  Passing coroutines objects to
 | |
|       ``wait()`` directly is deprecated as it leads to
 | |
|       :ref:`confusing behavior <asyncio_example_wait_coroutine>`.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
| 
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    .. _asyncio_example_wait_coroutine:
 | |
|    .. note::
 | |
| 
 | |
|       ``wait()`` schedules coroutines as Tasks automatically and later
 | |
|       returns those implicitly created Task objects in ``(done, pending)``
 | |
|       sets.  Therefore the following code won't work as expected::
 | |
| 
 | |
|           async def foo():
 | |
|               return 42
 | |
| 
 | |
|           coro = foo()
 | |
|           done, pending = await asyncio.wait({coro})
 | |
| 
 | |
|           if coro in done:
 | |
|               # This branch will never be run!
 | |
| 
 | |
|       Here is how the above snippet can be fixed::
 | |
| 
 | |
|           async def foo():
 | |
|               return 42
 | |
| 
 | |
|           task = asyncio.create_task(foo())
 | |
|           done, pending = await asyncio.wait({task})
 | |
| 
 | |
|           if task in done:
 | |
|               # Everything will work as expected now.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.11
 | |
| 
 | |
|       Passing coroutine objects to ``wait()`` directly is
 | |
|       deprecated.
 | |
| 
 | |
| 
 | |
| .. function:: as_completed(aws, *, loop=None, timeout=None)
 | |
| 
 | |
|    Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 | |
|    iterable concurrently.  Return an iterator of coroutines.
 | |
|    Each coroutine returned can be awaited to get the earliest next
 | |
|    result from the iterable of the remaining awaitables.
 | |
| 
 | |
|    Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
 | |
|    all Futures are done.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    Example::
 | |
| 
 | |
|        for coro in as_completed(aws):
 | |
|            earliest_result = await coro
 | |
|            # ...
 | |
| 
 | |
| 
 | |
| Running in Threads
 | |
| ==================
 | |
| 
 | |
| .. coroutinefunction:: to_thread(func, /, *args, **kwargs)
 | |
| 
 | |
|    Asynchronously run function *func* in a separate thread.
 | |
| 
 | |
|    Any \*args and \*\*kwargs supplied for this function are directly passed
 | |
|    to *func*. Also, the current :class:`contextvars.Context` is propagated,
 | |
|    allowing context variables from the event loop thread to be accessed in the
 | |
|    separate thread.
 | |
| 
 | |
|    Return a coroutine that can be awaited to get the eventual result of *func*.
 | |
| 
 | |
|    This coroutine function is primarily intended to be used for executing
 | |
|    IO-bound functions/methods that would otherwise block the event loop if
 | |
|    they were ran in the main thread. For example::
 | |
| 
 | |
|        def blocking_io():
 | |
|            print(f"start blocking_io at {time.strftime('%X')}")
 | |
|            # Note that time.sleep() can be replaced with any blocking
 | |
|            # IO-bound operation, such as file operations.
 | |
|            time.sleep(1)
 | |
|            print(f"blocking_io complete at {time.strftime('%X')}")
 | |
| 
 | |
|        async def main():
 | |
|            print(f"started main at {time.strftime('%X')}")
 | |
| 
 | |
|            await asyncio.gather(
 | |
|                asyncio.to_thread(blocking_io),
 | |
|                asyncio.sleep(1))
 | |
| 
 | |
|            print(f"finished main at {time.strftime('%X')}")
 | |
| 
 | |
| 
 | |
|        asyncio.run(main())
 | |
| 
 | |
|        # Expected output:
 | |
|        #
 | |
|        # started main at 19:50:53
 | |
|        # start blocking_io at 19:50:53
 | |
|        # blocking_io complete at 19:50:54
 | |
|        # finished main at 19:50:54
 | |
| 
 | |
|    Directly calling `blocking_io()` in any coroutine would block the event loop
 | |
|    for its duration, resulting in an additional 1 second of run time. Instead,
 | |
|    by using `asyncio.to_thread()`, we can run it in a separate thread without
 | |
|    blocking the event loop.
 | |
| 
 | |
|    .. note::
 | |
| 
 | |
|       Due to the :term:`GIL`, `asyncio.to_thread()` can typically only be used
 | |
|       to make IO-bound functions non-blocking. However, for extension modules
 | |
|       that release the GIL or alternative Python implementations that don't
 | |
|       have one, `asyncio.to_thread()` can also be used for CPU-bound functions.
 | |
| 
 | |
|    .. versionadded:: 3.9
 | |
| 
 | |
| 
 | |
| Scheduling From Other Threads
 | |
| =============================
 | |
| 
 | |
| .. function:: run_coroutine_threadsafe(coro, loop)
 | |
| 
 | |
|    Submit a coroutine to the given event loop.  Thread-safe.
 | |
| 
 | |
|    Return a :class:`concurrent.futures.Future` to wait for the result
 | |
|    from another OS thread.
 | |
| 
 | |
|    This function is meant to be called from a different OS thread
 | |
|    than the one where the event loop is running.  Example::
 | |
| 
 | |
|      # Create a coroutine
 | |
|      coro = asyncio.sleep(1, result=3)
 | |
| 
 | |
|      # Submit the coroutine to a given loop
 | |
|      future = asyncio.run_coroutine_threadsafe(coro, loop)
 | |
| 
 | |
|      # Wait for the result with an optional timeout argument
 | |
|      assert future.result(timeout) == 3
 | |
| 
 | |
|    If an exception is raised in the coroutine, the returned Future
 | |
|    will be notified.  It can also be used to cancel the task in
 | |
|    the event loop::
 | |
| 
 | |
|      try:
 | |
|          result = future.result(timeout)
 | |
|      except asyncio.TimeoutError:
 | |
|          print('The coroutine took too long, cancelling the task...')
 | |
|          future.cancel()
 | |
|      except Exception as exc:
 | |
|          print(f'The coroutine raised an exception: {exc!r}')
 | |
|      else:
 | |
|          print(f'The coroutine returned: {result!r}')
 | |
| 
 | |
|    See the :ref:`concurrency and multithreading <asyncio-multithreading>`
 | |
|    section of the documentation.
 | |
| 
 | |
|    Unlike other asyncio functions this function requires the *loop*
 | |
|    argument to be passed explicitly.
 | |
| 
 | |
|    .. versionadded:: 3.5.1
 | |
| 
 | |
| 
 | |
| Introspection
 | |
| =============
 | |
| 
 | |
| 
 | |
| .. function:: current_task(loop=None)
 | |
| 
 | |
|    Return the currently running :class:`Task` instance, or ``None`` if
 | |
|    no task is running.
 | |
| 
 | |
|    If *loop* is ``None`` :func:`get_running_loop` is used to get
 | |
|    the current loop.
 | |
| 
 | |
|    .. versionadded:: 3.7
 | |
| 
 | |
| 
 | |
| .. function:: all_tasks(loop=None)
 | |
| 
 | |
|    Return a set of not yet finished :class:`Task` objects run by
 | |
|    the loop.
 | |
| 
 | |
|    If *loop* is ``None``, :func:`get_running_loop` is used for getting
 | |
|    current loop.
 | |
| 
 | |
|    .. versionadded:: 3.7
 | |
| 
 | |
| 
 | |
| Task Object
 | |
| ===========
 | |
| 
 | |
| .. class:: Task(coro, *, loop=None, name=None)
 | |
| 
 | |
|    A :class:`Future-like <Future>` object that runs a Python
 | |
|    :ref:`coroutine <coroutine>`.  Not thread-safe.
 | |
| 
 | |
|    Tasks are used to run coroutines in event loops.
 | |
|    If a coroutine awaits on a Future, the Task suspends
 | |
|    the execution of the coroutine and waits for the completion
 | |
|    of the Future.  When the Future is *done*, the execution of
 | |
|    the wrapped coroutine resumes.
 | |
| 
 | |
|    Event loops use cooperative scheduling: an event loop runs
 | |
|    one Task at a time.  While a Task awaits for the completion of a
 | |
|    Future, the event loop runs other Tasks, callbacks, or performs
 | |
|    IO operations.
 | |
| 
 | |
|    Use the high-level :func:`asyncio.create_task` function to create
 | |
|    Tasks, or the low-level :meth:`loop.create_task` or
 | |
|    :func:`ensure_future` functions.  Manual instantiation of Tasks
 | |
|    is discouraged.
 | |
| 
 | |
|    To cancel a running Task use the :meth:`cancel` method.  Calling it
 | |
|    will cause the Task to throw a :exc:`CancelledError` exception into
 | |
|    the wrapped coroutine.  If a coroutine is awaiting on a Future
 | |
|    object during cancellation, the Future object will be cancelled.
 | |
| 
 | |
|    :meth:`cancelled` can be used to check if the Task was cancelled.
 | |
|    The method returns ``True`` if the wrapped coroutine did not
 | |
|    suppress the :exc:`CancelledError` exception and was actually
 | |
|    cancelled.
 | |
| 
 | |
|    :class:`asyncio.Task` inherits from :class:`Future` all of its
 | |
|    APIs except :meth:`Future.set_result` and
 | |
|    :meth:`Future.set_exception`.
 | |
| 
 | |
|    Tasks support the :mod:`contextvars` module.  When a Task
 | |
|    is created it copies the current context and later runs its
 | |
|    coroutine in the copied context.
 | |
| 
 | |
|    .. versionchanged:: 3.7
 | |
|       Added support for the :mod:`contextvars` module.
 | |
| 
 | |
|    .. versionchanged:: 3.8
 | |
|       Added the ``name`` parameter.
 | |
| 
 | |
|    .. deprecated-removed:: 3.8 3.10
 | |
|       The *loop* parameter.
 | |
| 
 | |
|    .. method:: cancel(msg=None)
 | |
| 
 | |
|       Request the Task to be cancelled.
 | |
| 
 | |
|       This arranges for a :exc:`CancelledError` exception to be thrown
 | |
|       into the wrapped coroutine on the next cycle of the event loop.
 | |
| 
 | |
|       The coroutine then has a chance to clean up or even deny the
 | |
|       request by suppressing the exception with a :keyword:`try` ...
 | |
|       ... ``except CancelledError`` ... :keyword:`finally` block.
 | |
|       Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does
 | |
|       not guarantee that the Task will be cancelled, although
 | |
|       suppressing cancellation completely is not common and is actively
 | |
|       discouraged.
 | |
| 
 | |
|       .. versionchanged:: 3.9
 | |
|          Added the ``msg`` parameter.
 | |
| 
 | |
|       .. _asyncio_example_task_cancel:
 | |
| 
 | |
|       The following example illustrates how coroutines can intercept
 | |
|       the cancellation request::
 | |
| 
 | |
|           async def cancel_me():
 | |
|               print('cancel_me(): before sleep')
 | |
| 
 | |
|               try:
 | |
|                   # Wait for 1 hour
 | |
|                   await asyncio.sleep(3600)
 | |
|               except asyncio.CancelledError:
 | |
|                   print('cancel_me(): cancel sleep')
 | |
|                   raise
 | |
|               finally:
 | |
|                   print('cancel_me(): after sleep')
 | |
| 
 | |
|           async def main():
 | |
|               # Create a "cancel_me" Task
 | |
|               task = asyncio.create_task(cancel_me())
 | |
| 
 | |
|               # Wait for 1 second
 | |
|               await asyncio.sleep(1)
 | |
| 
 | |
|               task.cancel()
 | |
|               try:
 | |
|                   await task
 | |
|               except asyncio.CancelledError:
 | |
|                   print("main(): cancel_me is cancelled now")
 | |
| 
 | |
|           asyncio.run(main())
 | |
| 
 | |
|           # Expected output:
 | |
|           #
 | |
|           #     cancel_me(): before sleep
 | |
|           #     cancel_me(): cancel sleep
 | |
|           #     cancel_me(): after sleep
 | |
|           #     main(): cancel_me is cancelled now
 | |
| 
 | |
|    .. method:: cancelled()
 | |
| 
 | |
|       Return ``True`` if the Task is *cancelled*.
 | |
| 
 | |
|       The Task is *cancelled* when the cancellation was requested with
 | |
|       :meth:`cancel` and the wrapped coroutine propagated the
 | |
|       :exc:`CancelledError` exception thrown into it.
 | |
| 
 | |
|    .. method:: done()
 | |
| 
 | |
|       Return ``True`` if the Task is *done*.
 | |
| 
 | |
|       A Task is *done* when the wrapped coroutine either returned
 | |
|       a value, raised an exception, or the Task was cancelled.
 | |
| 
 | |
|    .. method:: result()
 | |
| 
 | |
|       Return the result of the Task.
 | |
| 
 | |
|       If the Task is *done*, the result of the wrapped coroutine
 | |
|       is returned (or if the coroutine raised an exception, that
 | |
|       exception is re-raised.)
 | |
| 
 | |
|       If the Task has been *cancelled*, this method raises
 | |
|       a :exc:`CancelledError` exception.
 | |
| 
 | |
|       If the Task's result isn't yet available, this method raises
 | |
|       a :exc:`InvalidStateError` exception.
 | |
| 
 | |
|    .. method:: exception()
 | |
| 
 | |
|       Return the exception of the Task.
 | |
| 
 | |
|       If the wrapped coroutine raised an exception that exception
 | |
|       is returned.  If the wrapped coroutine returned normally
 | |
|       this method returns ``None``.
 | |
| 
 | |
|       If the Task has been *cancelled*, this method raises a
 | |
|       :exc:`CancelledError` exception.
 | |
| 
 | |
|       If the Task isn't *done* yet, this method raises an
 | |
|       :exc:`InvalidStateError` exception.
 | |
| 
 | |
|    .. method:: add_done_callback(callback, *, context=None)
 | |
| 
 | |
|       Add a callback to be run when the Task is *done*.
 | |
| 
 | |
|       This method should only be used in low-level callback-based code.
 | |
| 
 | |
|       See the documentation of :meth:`Future.add_done_callback`
 | |
|       for more details.
 | |
| 
 | |
|    .. method:: remove_done_callback(callback)
 | |
| 
 | |
|       Remove *callback* from the callbacks list.
 | |
| 
 | |
|       This method should only be used in low-level callback-based code.
 | |
| 
 | |
|       See the documentation of :meth:`Future.remove_done_callback`
 | |
|       for more details.
 | |
| 
 | |
|    .. method:: get_stack(*, limit=None)
 | |
| 
 | |
|       Return the list of stack frames for this Task.
 | |
| 
 | |
|       If the wrapped coroutine is not done, this returns the stack
 | |
|       where it is suspended.  If the coroutine has completed
 | |
|       successfully or was cancelled, this returns an empty list.
 | |
|       If the coroutine was terminated by an exception, this returns
 | |
|       the list of traceback frames.
 | |
| 
 | |
|       The frames are always ordered from oldest to newest.
 | |
| 
 | |
|       Only one stack frame is returned for a suspended coroutine.
 | |
| 
 | |
|       The optional *limit* argument sets the maximum number of frames
 | |
|       to return; by default all available frames are returned.
 | |
|       The ordering of the returned list differs depending on whether
 | |
|       a stack or a traceback is returned: the newest frames of a
 | |
|       stack are returned, but the oldest frames of a traceback are
 | |
|       returned.  (This matches the behavior of the traceback module.)
 | |
| 
 | |
|    .. method:: print_stack(*, limit=None, file=None)
 | |
| 
 | |
|       Print the stack or traceback for this Task.
 | |
| 
 | |
|       This produces output similar to that of the traceback module
 | |
|       for the frames retrieved by :meth:`get_stack`.
 | |
| 
 | |
|       The *limit* argument is passed to :meth:`get_stack` directly.
 | |
| 
 | |
|       The *file* argument is an I/O stream to which the output
 | |
|       is written; by default output is written to :data:`sys.stderr`.
 | |
| 
 | |
|    .. method:: get_coro()
 | |
| 
 | |
|       Return the coroutine object wrapped by the :class:`Task`.
 | |
| 
 | |
|       .. versionadded:: 3.8
 | |
| 
 | |
|    .. method:: get_name()
 | |
| 
 | |
|       Return the name of the Task.
 | |
| 
 | |
|       If no name has been explicitly assigned to the Task, the default
 | |
|       asyncio Task implementation generates a default name during
 | |
|       instantiation.
 | |
| 
 | |
|       .. versionadded:: 3.8
 | |
| 
 | |
|    .. method:: set_name(value)
 | |
| 
 | |
|       Set the name of the Task.
 | |
| 
 | |
|       The *value* argument can be any object, which is then
 | |
|       converted to a string.
 | |
| 
 | |
|       In the default Task implementation, the name will be visible
 | |
|       in the :func:`repr` output of a task object.
 | |
| 
 | |
|       .. versionadded:: 3.8
 | |
| 
 | |
| 
 | |
| .. _asyncio_generator_based_coro:
 | |
| 
 | |
| Generator-based Coroutines
 | |
| ==========================
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|    Support for generator-based coroutines is **deprecated** and
 | |
|    is scheduled for removal in Python 3.10.
 | |
| 
 | |
| Generator-based coroutines predate async/await syntax.  They are
 | |
| Python generators that use ``yield from`` expressions to await
 | |
| on Futures and other coroutines.
 | |
| 
 | |
| Generator-based coroutines should be decorated with
 | |
| :func:`@asyncio.coroutine <asyncio.coroutine>`, although this is not
 | |
| enforced.
 | |
| 
 | |
| 
 | |
| .. decorator:: coroutine
 | |
| 
 | |
|     Decorator to mark generator-based coroutines.
 | |
| 
 | |
|     This decorator enables legacy generator-based coroutines to be
 | |
|     compatible with async/await code::
 | |
| 
 | |
|         @asyncio.coroutine
 | |
|         def old_style_coroutine():
 | |
|             yield from asyncio.sleep(1)
 | |
| 
 | |
|         async def main():
 | |
|             await old_style_coroutine()
 | |
| 
 | |
|     This decorator should not be used for :keyword:`async def`
 | |
|     coroutines.
 | |
| 
 | |
|     .. deprecated-removed:: 3.8 3.10
 | |
| 
 | |
|        Use :keyword:`async def` instead.
 | |
| 
 | |
| .. function:: iscoroutine(obj)
 | |
| 
 | |
|    Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`.
 | |
| 
 | |
|    This method is different from :func:`inspect.iscoroutine` because
 | |
|    it returns ``True`` for generator-based coroutines.
 | |
| 
 | |
| .. function:: iscoroutinefunction(func)
 | |
| 
 | |
|    Return ``True`` if *func* is a :ref:`coroutine function
 | |
|    <coroutine>`.
 | |
| 
 | |
|    This method is different from :func:`inspect.iscoroutinefunction`
 | |
|    because it returns ``True`` for generator-based coroutine functions
 | |
|    decorated with :func:`@coroutine <coroutine>`.
 |