bpo-33649: Refresh Tasks and Futures pages (#9314)

* bpo-33649: Refresh Tasks and Futures pages

* Fixes

* Fix markup
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 9f4433d..7e09b16 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1,96 +1,118 @@
 .. currentmodule:: asyncio
 
-Tasks and coroutines
+
+====================
+Coroutines and Tasks
 ====================
 
-**Source code:** :source:`Lib/asyncio/tasks.py`
+This section outlines high-level asyncio APIs to work with coroutines
+and Tasks.
 
-**Source code:** :source:`Lib/asyncio/coroutines.py`
+.. contents::
+   :depth: 1
+   :local:
+
 
 .. _coroutine:
 
 Coroutines
-----------
+==========
 
-Coroutines used with :mod:`asyncio` may be implemented using the
-:keyword:`async def` statement, or by using :term:`generators <generator>`.
-The :keyword:`async def` type of coroutine was added in Python 3.5, and
-is recommended if there is no need to support older Python versions.
+Coroutines declared with async/await syntax is the preferred way of
+writing asyncio applications.  For example, the following snippet
+of code prints "hello", waits 1 second, and prints "world"::
 
-Generator-based coroutines should be decorated with :func:`@asyncio.coroutine
-<asyncio.coroutine>`, although this is not strictly enforced.
-The decorator enables compatibility with :keyword:`async def` coroutines,
-and also serves as documentation.  Generator-based
-coroutines use the ``yield from`` syntax introduced in :pep:`380`,
-instead of the original ``yield`` syntax.
+    >>> import asyncio
 
-The word "coroutine", like the word "generator", is used for two
-different (though related) concepts:
+    >>> async def main():
+    ...     print('hello')
+    ...     await asyncio.sleep(1)
+    ...     print('world')
 
-- The function that defines a coroutine
-  (a function definition using :keyword:`async def` or
-  decorated with ``@asyncio.coroutine``).  If disambiguation is needed
-  we will call this a *coroutine function* (:func:`iscoroutinefunction`
-  returns ``True``).
+    >>> asyncio.run(main())
+    hello
+    world
 
-- The object obtained by calling a coroutine function.  This object
-  represents a computation or an I/O operation (usually a combination)
-  that will complete eventually.  If disambiguation is needed we will
-  call it a *coroutine object* (:func:`iscoroutine` returns ``True``).
+Note that simply calling a coroutine will not schedule it to
+be executed::
 
-Things a coroutine can do:
+    >>> main()
+    <coroutine object main at 0x1053bb7c8>
 
-- ``result = await future`` or ``result = yield from future`` --
-  suspends the coroutine until the
-  future is done, then returns the future's result, or raises an
-  exception, which will be propagated.  (If the future is cancelled,
-  it will raise a ``CancelledError`` exception.)  Note that tasks are
-  futures, and everything said about futures also applies to tasks.
+To actually run a coroutine asyncio provides three main mechanisms:
 
-- ``result = await coroutine`` or ``result = yield from coroutine`` --
-  wait for another coroutine to
-  produce a result (or raise an exception, which will be propagated).
-  The ``coroutine`` expression must be a *call* to another coroutine.
+* By using the :func:`asyncio.run` function to run the top-level
+  entry point "main()" function (see the above example.)
 
-- ``return expression`` -- produce a result to the coroutine that is
-  waiting for this one using :keyword:`await` or ``yield from``.
+* By 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::
 
-- ``raise exception`` -- raise an exception in the coroutine that is
-  waiting for this one using :keyword:`await` or ``yield from``.
+      import asyncio
+      import time
 
-Calling a coroutine does not start its code running --
-the coroutine object returned by the call doesn't do anything until you
-schedule its execution.  There are two basic ways to start it running:
-call ``await coroutine`` or ``yield from coroutine`` from another coroutine
-(assuming the other coroutine is already running!), or schedule its execution
-using the :func:`ensure_future` function or the :meth:`loop.create_task`
-method.
+      async def say_after(delay, what):
+          await asyncio.sleep(delay)
+          print(what)
+
+      async def main():
+          print('started at', time.strftime('%X'))
+
+          await say_after(1, 'hello')
+          await say_after(2, 'world')
+
+          print('finished at', time.strftime('%X'))
+
+      asyncio.run(main())
+
+  Expected output::
+
+      started at 17:13:52
+      hello
+      world
+      finished at 17:13:55
+
+* By using the :func:`asyncio.create_task` function to run coroutines
+  concurrently as asyncio :class:`Tasks <Task>`.
+
+  Let's modify the above example and run two "set_after" coroutines
+  *concurrently*::
+
+      async def main():
+          task1 = asyncio.create_task(
+              say_after(1, 'hello'))
+
+          task2 = asyncio.create_task(
+              say_after(2, 'world'))
+
+          print('started at', time.strftime('%X'))
+
+          # Wait until both tasks are completed (should take
+          # around 2 seconds.)
+          await task1
+          await task2
+
+          print('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
+
+Note that 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*: object returned by calling a
+  *coroutine function*.
 
 
-Coroutines (and tasks) can only run when the event loop is running.
-
-.. decorator:: coroutine
-
-    Decorator to mark generator-based coroutines.  This enables
-    the generator use :keyword:`!yield from` to call :keyword:`async
-    def` coroutines, and also enables the generator to be called by
-    :keyword:`async def` coroutines, for instance using an
-    :keyword:`await` expression.
-
-    There is no need to decorate :keyword:`async def` coroutines themselves.
-
-    If the generator is not yielded from before it is destroyed, an error
-    message is logged. See :ref:`Detect coroutines never scheduled
-    <asyncio-coroutine-not-scheduled>`.
-
-.. note::
-
-    In this documentation, some methods are documented as coroutines,
-    even if they are plain Python functions returning a :class:`Future`.
-    This is intentional to have a freedom of tweaking the implementation
-    of these functions in the future. If such a function is needed to be
-    used in a callback-style code, wrap its result with :func:`ensure_future`.
-
+Running an asyncio Program
+==========================
 
 .. function:: run(coro, \*, debug=False)
 
@@ -101,7 +123,7 @@
     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.
+    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
@@ -112,260 +134,8 @@
        on a :term:`provisional basis <provisional api>`.
 
 
-.. _asyncio-hello-world-coroutine:
-
-Example: Hello World coroutine
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Example of coroutine displaying ``"Hello World"``::
-
-    import asyncio
-
-    async def hello_world():
-        print("Hello World!")
-
-    asyncio.run(hello_world())
-
-.. seealso::
-
-   The :ref:`Hello World with call_soon() <asyncio-hello-world-callback>`
-   example uses the :meth:`loop.call_soon` method to schedule a
-   callback.
-
-
-.. _asyncio-date-coroutine:
-
-Example: Coroutine displaying the current date
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Example of coroutine displaying the current date every second during 5 seconds
-using the :meth:`sleep` function::
-
-    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())
-
-.. seealso::
-
-   The :ref:`display the current date with call_later()
-   <asyncio-date-callback>` example uses a callback with the
-   :meth:`loop.call_later` method.
-
-
-Example: Chain coroutines
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Example chaining coroutines::
-
-    import asyncio
-
-    async def compute(x, y):
-        print("Compute %s + %s ..." % (x, y))
-        await asyncio.sleep(1.0)
-        return x + y
-
-    async def print_sum(x, y):
-        result = await compute(x, y)
-        print("%s + %s = %s" % (x, y, result))
-
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(print_sum(1, 2))
-    loop.close()
-
-``compute()`` is chained to ``print_sum()``: ``print_sum()`` coroutine waits
-until ``compute()`` is completed before returning its result.
-
-Sequence diagram of the example:
-
-.. image:: tulip_coro.png
-   :align: center
-
-The "Task" is created by the :meth:`loop.run_until_complete` method
-when it gets a coroutine object instead of a task.
-
-The diagram shows the control flow, it does not describe exactly how things
-work internally. For example, the sleep coroutine creates an internal future
-which uses :meth:`loop.call_later` to wake up the task in 1 second.
-
-
-Future
-------
-
-.. class:: Future(\*, loop=None)
-
-   This class is *almost* compatible with :class:`concurrent.futures.Future`.
-
-   Differences:
-
-   - :meth:`result` and :meth:`exception` do not take a timeout argument and
-     raise an exception when the future isn't done yet.
-
-   - Callbacks registered with :meth:`add_done_callback` are always called
-     via the event loop's :meth:`loop.call_soon`.
-
-   - This class is not compatible with the :func:`~concurrent.futures.wait` and
-     :func:`~concurrent.futures.as_completed` functions in the
-     :mod:`concurrent.futures` package.
-
-   This class is :ref:`not thread safe <asyncio-multithreading>`.
-
-   .. method:: cancel()
-
-      Cancel the future and schedule callbacks.
-
-      If the future is already done or cancelled, return ``False``. Otherwise,
-      change the future's state to cancelled, schedule the callbacks and return
-      ``True``.
-
-   .. method:: cancelled()
-
-      Return ``True`` if the future was cancelled.
-
-   .. method:: done()
-
-      Return ``True`` if the future is done.
-
-      Done means either that a result / exception are available, or that the
-      future was cancelled.
-
-   .. method:: result()
-
-      Return the result this future represents.
-
-      If the future has been cancelled, raises :exc:`CancelledError`. If the
-      future's result isn't yet available, raises :exc:`InvalidStateError`. If
-      the future is done and has an exception set, this exception is raised.
-
-   .. method:: exception()
-
-      Return the exception that was set on this future.
-
-      The exception (or ``None`` if no exception was set) is returned only if
-      the future is done. If the future has been cancelled, raises
-      :exc:`CancelledError`. If the future isn't done yet, raises
-      :exc:`InvalidStateError`.
-
-   .. method:: add_done_callback(callback, *, context=None)
-
-      Add a callback to be run when the future becomes done.
-
-      The *callback* is called with a single argument - the future object. If the
-      future is already done when this is called, the callback is scheduled
-      with :meth:`loop.call_soon`.
-
-      An optional keyword-only *context* argument allows specifying a custom
-      :class:`contextvars.Context` for the *callback* to run in.  The current
-      context is used when no *context* is provided.
-
-      :ref:`Use functools.partial to pass parameters to the callback
-      <asyncio-pass-keywords>`. For example,
-      ``fut.add_done_callback(functools.partial(print, "Future:",
-      flush=True))`` will call ``print("Future:", fut, flush=True)``.
-
-      .. versionchanged:: 3.7
-         The *context* keyword-only parameter was added. See :pep:`567`
-         for more details.
-
-   .. method:: remove_done_callback(fn)
-
-      Remove all instances of a callback from the "call when done" list.
-
-      Returns the number of callbacks removed.
-
-   .. method:: set_result(result)
-
-      Mark the future done and set its result.
-
-      If the future is already done when this method is called, raises
-      :exc:`InvalidStateError`.
-
-   .. method:: set_exception(exception)
-
-      Mark the future done and set an exception.
-
-      If the future is already done when this method is called, raises
-      :exc:`InvalidStateError`.
-
-   .. method:: get_loop()
-
-      Return the event loop the future object is bound to.
-
-      .. versionadded:: 3.7
-
-
-Example: Future with run_until_complete()
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Example combining a :class:`Future` and a :ref:`coroutine function
-<coroutine>`::
-
-    import asyncio
-
-    async def slow_operation(future):
-        await asyncio.sleep(1)
-        future.set_result('Future is done!')
-
-    loop = asyncio.get_event_loop()
-    future = asyncio.Future()
-    asyncio.ensure_future(slow_operation(future))
-    loop.run_until_complete(future)
-    print(future.result())
-    loop.close()
-
-The coroutine function is responsible for the computation (which takes 1 second)
-and it stores the result into the future. The
-:meth:`loop.run_until_complete` method waits for the completion of
-the future.
-
-.. note::
-   The :meth:`loop.run_until_complete` method uses internally the
-   :meth:`~Future.add_done_callback` method to be notified when the future is
-   done.
-
-
-Example: Future with run_forever()
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The previous example can be written differently using the
-:meth:`Future.add_done_callback` method to describe explicitly the control
-flow::
-
-    import asyncio
-
-    async def slow_operation(future):
-        await asyncio.sleep(1)
-        future.set_result('Future is done!')
-
-    def got_result(future):
-        print(future.result())
-        loop.stop()
-
-    loop = asyncio.get_event_loop()
-    future = asyncio.Future()
-    asyncio.ensure_future(slow_operation(future))
-    future.add_done_callback(got_result)
-    try:
-        loop.run_forever()
-    finally:
-        loop.close()
-
-In this example, the future is used to link ``slow_operation()`` to
-``got_result()``: when ``slow_operation()`` is done, ``got_result()`` is called
-with the result.
-
-
-Task
-----
+Creating Tasks
+==============
 
 .. function:: create_task(coro, \*, name=None)
 
@@ -384,359 +154,136 @@
    .. versionchanged:: 3.8
       Added the ``name`` parameter.
 
-.. class:: Task(coro, \*, loop=None, name=None)
 
-   A unit for concurrent running of :ref:`coroutines <coroutine>`,
-   subclass of :class:`Future`.
-
-   A task is responsible for executing a coroutine object in an event loop.  If
-   the wrapped coroutine yields from a future, the task suspends the execution
-   of the wrapped coroutine and waits for the completion of the future. When
-   the future is done, the execution of the wrapped coroutine restarts with the
-   result or the exception of the future.
-
-   Event loops use cooperative scheduling: an event loop only runs one task at
-   a time. Other tasks may run in parallel if other event loops are
-   running in different threads. While a task waits for the completion of a
-   future, the event loop executes a new task.
-
-   The cancellation of a task is different from the cancellation of a
-   future. Calling :meth:`cancel` will throw a
-   :exc:`~concurrent.futures.CancelledError` to the wrapped
-   coroutine. :meth:`~Future.cancelled` only returns ``True`` if the
-   wrapped coroutine did not catch the
-   :exc:`~concurrent.futures.CancelledError` exception, or raised a
-   :exc:`~concurrent.futures.CancelledError` exception.
-
-   If a pending task is destroyed, the execution of its wrapped :ref:`coroutine
-   <coroutine>` did not complete. It is probably a bug and a warning is
-   logged: see :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`.
-
-   Don't directly create :class:`Task` instances: use the :func:`create_task`
-   function or the :meth:`loop.create_task` method.
-
-   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.  See :pep:`567` for more details.
-
-   This class is :ref:`not thread safe <asyncio-multithreading>`.
-
-   .. versionchanged:: 3.7
-      Added support for the :mod:`contextvars` module.
-
-   .. versionchanged:: 3.8
-      Added the ``name`` parameter.
-
-   .. classmethod:: all_tasks(loop=None)
-
-      Return a set of all tasks for an event loop.
-
-      By default all tasks for the current event loop are returned.
-      If *loop* is ``None``, :func:`get_event_loop` function
-      is used to get the current loop.
-
-   .. classmethod:: current_task(loop=None)
-
-      Return the currently running task in an event loop or ``None``.
-
-      By default the current task for the current event loop is returned.
-
-      ``None`` is returned when called not in the context of a :class:`Task`.
-
-   .. method:: cancel()
-
-      Request that this task cancel itself.
-
-      This arranges for a :exc:`~concurrent.futures.CancelledError` to be
-      thrown into the wrapped coroutine on the next cycle through the event
-      loop. The coroutine then has a chance to clean up or even deny the
-      request using try/except/finally.
-
-      Unlike :meth:`Future.cancel`, this does not guarantee that the task
-      will be cancelled: the exception might be caught and acted upon, delaying
-      cancellation of the task or preventing cancellation completely. The task
-      may also return a value or raise a different exception.
-
-      Immediately after this method is called, :meth:`~Future.cancelled` will
-      not return ``True`` (unless the task was already cancelled). A task will
-      be marked as cancelled when the wrapped coroutine terminates with a
-      :exc:`~concurrent.futures.CancelledError` exception (even if
-      :meth:`cancel` was not called).
-
-   .. method:: get_stack(\*, limit=None)
-
-      Return the list of stack frames for this task's coroutine.
-
-      If the 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.
-
-      The optional limit gives the maximum number of frames to return; by
-      default all available frames are returned.  Its meaning 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.)
-
-      For reasons beyond our control, only one stack frame is returned for a
-      suspended coroutine.
-
-   .. method:: print_stack(\*, limit=None, file=None)
-
-      Print the stack or traceback for this task's coroutine.
-
-      This produces output similar to that of the traceback module, for the
-      frames retrieved by get_stack().  The limit argument is passed to
-      get_stack().  The file argument is an I/O stream to which the output
-      is written; by default output is written to sys.stderr.
-
-   .. method:: get_name()
-
-      Return the name of the task.
-
-      If no name has been explicitly assigned to the task, the default
-      ``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
-
-
-Example: Parallel execution of tasks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Example executing 3 tasks (A, B, C) in parallel::
-
-    import asyncio
-
-    async def factorial(name, number):
-        f = 1
-        for i in range(2, number+1):
-            print("Task %s: Compute factorial(%s)..." % (name, i))
-            await asyncio.sleep(1)
-            f *= i
-        print("Task %s: factorial(%s) = %s" % (name, number, f))
-
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(asyncio.gather(
-        factorial("A", 2),
-        factorial("B", 3),
-        factorial("C", 4),
-    ))
-    loop.close()
-
-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
-
-A task is automatically scheduled for execution when it is created. The event
-loop stops when all tasks are done.
-
-
-Task functions
---------------
-
-.. note::
-
-   In the functions below, the optional *loop* argument allows explicitly setting
-   the event loop object used by the underlying task or coroutine.  If it's
-   not provided, the default event loop is used.
-
-
-.. function:: current_task(loop=None)
-
-   Return the current 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 :class:`Task` objects created for the loop.
-
-   If *loop* is ``None``, :func:`get_running_loop` is used for getting
-   current loop (contrary to the deprecated :meth:`Task.all_tasks` method
-   that uses :func:`get_event_loop`.)
-
-   .. versionadded:: 3.7
-
-
-.. function:: as_completed(fs, \*, loop=None, timeout=None)
-
-   Return an iterator whose values, when waited for, are :class:`Future`
-   instances.
-
-   Raises :exc:`asyncio.TimeoutError` if the timeout occurs before all Futures
-   are done.
-
-   Example::
-
-       for f in as_completed(fs):
-           result = await f  # The 'await' may raise
-           # Use result
-
-   .. note::
-
-      The futures ``f`` are not necessarily members of fs.
-
-.. function:: ensure_future(coro_or_future, \*, loop=None)
-
-   Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in
-   a future. Return a :class:`Task` object.
-
-   If the argument is a :class:`Future`, it is returned directly.
-
-   .. versionadded:: 3.4.4
-
-   .. versionchanged:: 3.5.1
-      The function accepts any :term:`awaitable` object.
-
-   .. note::
-
-      :func:`create_task` (added in Python 3.7) is the preferable way
-      for spawning new tasks.
-
-   .. seealso::
-
-      The :func:`create_task` function and
-      :meth:`loop.create_task` method.
-
-.. function:: wrap_future(future, \*, loop=None)
-
-   Wrap a :class:`concurrent.futures.Future` object in a :class:`Future`
-   object.
-
-.. function:: gather(\*coros_or_futures, loop=None, return_exceptions=False)
-
-   Return a future aggregating results from the given coroutine objects or
-   futures.
-
-   All futures must share the same event loop.  If all the tasks are done
-   successfully, the returned future's result is the list of results (in the
-   order of the original sequence, not necessarily the order of results
-   arrival).  If *return_exceptions* is true, exceptions in the tasks are
-   treated the same as successful results, and gathered in the result list;
-   otherwise, the first raised exception will be immediately propagated to the
-   returned future.
-
-   Cancellation: if the outer Future is cancelled, all children (that have not
-   completed yet) are also cancelled.  If any child is cancelled, this is
-   treated as if it raised :exc:`~concurrent.futures.CancelledError` -- the
-   outer Future is *not* cancelled in this case.  (This is to prevent the
-   cancellation of one child to cause other children to be cancelled.)
-
-   .. versionchanged:: 3.7.0
-      If the *gather* itself is cancelled, the cancellation is propagated
-      regardless of *return_exceptions*.
-
-.. function:: iscoroutine(obj)
-
-   Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`,
-   which may be based on a generator or an :keyword:`async def` coroutine.
-
-.. function:: iscoroutinefunction(func)
-
-   Return ``True`` if *func* is determined to be a :ref:`coroutine function
-   <coroutine>`, which may be a decorated generator function or an
-   :keyword:`async def` function.
-
-.. function:: run_coroutine_threadsafe(coro, loop)
-
-   Submit a :ref:`coroutine object <coroutine>` to a given event loop.
-
-   Return a :class:`concurrent.futures.Future` to access the result.
-
-   This function is meant to be called from a different thread than the one
-   where the event loop is running. Usage::
-
-     # 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('The coroutine raised an exception: {!r}'.format(exc))
-     else:
-         print('The coroutine returned: {!r}'.format(result))
-
-   See the :ref:`concurrency and multithreading <asyncio-multithreading>`
-   section of the documentation.
-
-   .. note::
-
-      Unlike other functions from the module,
-      :func:`run_coroutine_threadsafe` requires the *loop* argument to
-      be passed explicitly.
-
-   .. versionadded:: 3.5.1
+Sleeping
+========
 
 .. coroutinefunction:: sleep(delay, result=None, \*, loop=None)
 
-   Create a :ref:`coroutine <coroutine>` that completes after a given
-   time (in seconds).  If *result* is provided, it is produced to the caller
+   Block for *delay* seconds.
+
+   If *result* is provided, it is returned to the caller
    when the coroutine completes.
 
-   The resolution of the sleep depends on the :ref:`granularity of the event
-   loop <asyncio-delayed-calls>`.
+   .. _asyncio-date-coroutine:
 
-   This function is a :ref:`coroutine <coroutine>`.
+   Example of coroutine displaying the current date every second
+   during 5 seconds::
 
-.. coroutinefunction:: shield(arg, \*, loop=None)
+    import asyncio
+    import datetime
 
-   Wait for a future, shielding it from cancellation.
+    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
+==========================
+
+.. coroutinefunction:: gather(\*fs, loop=None, return_exceptions=False)
+
+   Return a Future aggregating results from the given coroutine objects,
+   Tasks, or Futures.
+
+   If all Tasks/Futures are completed successfully, the result is an
+   aggregate list of returned values.  The result values are in the
+   order of the original *fs* sequence.
+
+   All coroutines in the *fs* list are automatically
+   wrapped in :class:`Tasks <Task>`.
+
+   If *return_exceptions* is ``True``, exceptions in the Tasks/Futures
+   are treated the same as successful results, and gathered in the
+   result list.  Otherwise, the first raised exception is immediately
+   propagated to the returned Future.
+
+   If the outer Future is *cancelled*, all submitted Tasks/Futures
+   (that have not completed yet) are also *cancelled*.
+
+   If any child is *cancelled*, it is treated as if it raised
+   :exc:`CancelledError` -- the outer Future 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.
+
+   All futures must share the same event loop.
+
+   .. versionchanged:: 3.7
+      If the *gather* itself is cancelled, the cancellation is
+      propagated regardless of *return_exceptions*.
+
+   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():
+          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
+
+
+Shielding Tasks From Cancellation
+=================================
+
+.. coroutinefunction:: shield(fut, \*, loop=None)
+
+   Wait for a Future/Task while protecting it from being cancelled.
+
+   *fut* can be a coroutine, a Task, or a Future-like object.  If
+   *fut* is a coroutine it is automatically wrapped in a
+   :class:`Task`.
 
    The statement::
 
        res = await shield(something())
 
-   is exactly equivalent to the statement::
+   is equivalent to the statement::
 
        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.  But its caller is still
-   cancelled, so the yield-from expression still raises
-   :exc:`~concurrent.futures.CancelledError`.  Note: If ``something()`` is
-   cancelled by other means this will still cancel ``shield()``.
+   *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 :exc:`CancelledError`.
 
-   If you want to completely ignore cancellation (not recommended) you can
-   combine ``shield()`` with a try/except clause, as follows::
+   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())
@@ -744,21 +291,79 @@
            res = None
 
 
-.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None,\
+Timeouts
+========
+
+.. coroutinefunction:: wait_for(fut, timeout, \*, loop=None)
+
+   Wait for the coroutine, Task, or Future to complete with timeout.
+
+   *fut* can be a coroutine, a Task, or a Future-like object.  If
+   *fut* is a coroutine it is automatically wrapped in a
+   :class:`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 cancellation, 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 the wait is cancelled, the future *fut* is also cancelled.
+
+   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 *fut* is cancelled due to a timeout, ``wait_for`` waits
+      for *fut* to be cancelled.  Previously, it raised
+      :exc:`asyncio.TimeoutError` immediately.
+
+
+Waiting Primitives
+==================
+
+.. coroutinefunction:: wait(fs, \*, loop=None, timeout=None,\
                             return_when=ALL_COMPLETED)
 
-   Wait for the Futures and coroutine objects given by the sequence *futures*
-   to complete.  Coroutines will be wrapped in Tasks. Returns two sets of
-   :class:`Future`: (done, pending).
+   Wait for a set of Futures to complete.
 
-   The sequence *futures* must not be empty.
+   *fs* is a list of coroutines, Futures, and/or Tasks.  Coroutines
+   are automatically wrapped in :class:`Tasks <Task>`.
 
-   *timeout* can be used to control the maximum number of seconds to wait before
-   returning.  *timeout* can be an int or float.  If *timeout* is not specified
-   or ``None``, there is no limit to the wait time.
+   Returns two sets of Tasks/Futures: ``(done, pending)``.
 
-   *return_when* indicates when this function should return.  It must be one of
-   the following constants of the :mod:`concurrent.futures` module:
+   *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 just
+   returned in the second set.
+
+   *return_when* indicates when this function should return.  It must
+   be one of the following constants:
 
    .. tabularcolumns:: |l|L|
 
@@ -778,45 +383,343 @@
    |                             | futures finish or are cancelled.       |
    +-----------------------------+----------------------------------------+
 
-   Unlike :func:`~asyncio.wait_for`, ``wait()`` will not cancel the futures
-   when a timeout occurs.
-
-   This function is a :ref:`coroutine <coroutine>`.
+   Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the
+   futures when a timeout occurs.
 
    Usage::
 
         done, pending = await asyncio.wait(fs)
 
-   .. note::
 
-      This does not raise :exc:`asyncio.TimeoutError`! Futures that aren't done
-      when the timeout occurs are returned in the second set.
+.. function:: as_completed(fs, \*, loop=None, timeout=None)
+
+   Return an iterator which values, when waited for, are
+   :class:`Future` instances.
+
+   Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
+   all Futures are done.
+
+   Example::
+
+       for f in as_completed(fs):
+           result = await f
+           # ...
 
 
-.. coroutinefunction:: wait_for(fut, timeout, \*, loop=None)
+Scheduling From Other Threads
+=============================
 
-   Wait for the single :class:`Future` or :ref:`coroutine object <coroutine>`
-   to complete with timeout. If *timeout* is ``None``, block until the future
-   completes.
+.. function:: run_coroutine_threadsafe(coro, loop)
 
-   Coroutine will be wrapped in :class:`Task`.
+   Submit a coroutine to the given event loop.  Thread-safe.
 
-   Returns result of the Future or coroutine.  When a timeout occurs, it
-   cancels the task and raises :exc:`asyncio.TimeoutError`. To avoid the task
-   cancellation, wrap it in :func:`shield`.  The function will wait until
-   the future is actually cancelled, so the total wait time may exceed
-   the *timeout*.
+   Return a :class:`concurrent.futures.Future` to access the result.
 
-   If the wait is cancelled, the future *fut* is also cancelled.
+   This function is meant to be called from a different OS thread
+   than the one where the event loop is running.  Example::
 
-   This function is a :ref:`coroutine <coroutine>`, usage::
+     # Create a coroutine
+     coro = asyncio.sleep(1, result=3)
 
-       result = await asyncio.wait_for(fut, 60.0)
+     # Submit the coroutine to a given loop
+     future = asyncio.run_coroutine_threadsafe(coro, loop)
 
-   .. versionchanged:: 3.4.3
-      If the wait is cancelled, the future *fut* is now also cancelled.
+     # 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('The coroutine raised an exception: {!r}'.format(exc))
+     else:
+         print('The coroutine returned: {!r}'.format(result))
+
+   See the :ref:`concurrency and multithreading <asyncio-multithreading>`
+   section of the documentation.
+
+   Unlike other asyncio functions this functions 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 object that wraps 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 low-level :meth:`loop.create_task` or
+   :func:`ensure_future` functions.  Manually instantiating Task
+   objects 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
-      When *fut* is cancelled due to a timeout, ``wait_for`` now waits
-      for *fut* to be cancelled.  Previously,
-      it raised :exc:`~asyncio.TimeoutError` immediately.
+      Added support for the :mod:`contextvars` module.
+
+   .. versionchanged:: 3.8
+      Added the ``name`` parameter.
+
+   .. method:: cancel()
+
+      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.
+
+      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:: 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_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
+
+   .. classmethod:: all_tasks(loop=None)
+
+      Return a set of all tasks for an event loop.
+
+      By default all tasks for the current event loop are returned.
+      If *loop* is ``None``, the :func:`get_event_loop` function
+      is used to get the current loop.
+
+      This function is **deprecated** and scheduled for removal in
+      Python 3.9.  Use the :func:`all_tasks` function instead.
+
+   .. classmethod:: current_task(loop=None)
+
+      Return the currently running task or ``None``.
+
+      If *loop* is ``None``, the :func:`get_event_loop` function
+      is used to get the current loop.
+
+      This function is **deprecated** and scheduled for removal in
+      Python 3.9.  Use the :func:`current_task` function instead.
+
+
+.. _asyncio_generator_based_coro:
+
+Generator-based Coroutines
+==========================
+
+.. note::
+
+   Support for generator-based coroutines is **deprecated** and
+   scheduled for removal in Python 4.0.
+
+Generator-based coroutines predate async/await syntax.  They are
+Python generators that use ``yield from`` expression is 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 is **deprecated** and is scheduled for removal in
+    Python 4.0.
+
+    This decorator should not be used for :keyword:`async def`
+    coroutines.
+
+.. 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 decorated with
+   :func:`@coroutine <coroutine>`.
+
+.. 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>`.