]> granicus.if.org Git - python/commitdiff
bpo-34790: [docs] Passing coroutines to asyncio.wait() can be confusing. (GH-9543)
authorYury Selivanov <yury@magic.io>
Tue, 25 Sep 2018 18:51:21 +0000 (14:51 -0400)
committerGitHub <noreply@github.com>
Tue, 25 Sep 2018 18:51:21 +0000 (14:51 -0400)
Doc/library/asyncio-task.rst
Misc/NEWS.d/next/Documentation/2018-09-24-12-47-08.bpo-34790.G2KXIH.rst [new file with mode: 0644]

index e995fb6391adb666e4776f6315449436f69c9ac0..bb693d7a647582f947bdf2f2d5101c44910247f2 100644 (file)
@@ -472,14 +472,20 @@ Waiting Primitives
                             return_when=ALL_COMPLETED)
 
    Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
-   sequence concurrently and block until the condition specified
+   set concurrently and block until the condition specified
    by *return_when*.
 
    If any awaitable in *aws* is a coroutine, it is automatically
-   scheduled as a Task.
+   scheduled as a Task.  Passing coroutines objects to
+   ``wait()`` directly is deprecated as it leads to
+   :ref:`confusing behavior <asyncio_example_wait_coroutine>`.
 
    Returns two sets of Tasks/Futures: ``(done, pending)``.
 
+   Usage::
+
+        done, pending = await asyncio.wait(aws)
+
    The *loop* argument is deprecated and scheduled for removal
    in Python 4.0.
 
@@ -514,9 +520,35 @@ Waiting Primitives
    Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the
    futures when a timeout occurs.
 
-   Usage::
+   .. _asyncio_example_wait_coroutine:
+   .. note::
 
-        done, pending = await asyncio.wait(aws)
+      ``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.
+
+      Passing coroutine objects to ``wait()`` directly is
+      deprecated.
 
 
 .. function:: as_completed(aws, \*, loop=None, timeout=None)
diff --git a/Misc/NEWS.d/next/Documentation/2018-09-24-12-47-08.bpo-34790.G2KXIH.rst b/Misc/NEWS.d/next/Documentation/2018-09-24-12-47-08.bpo-34790.G2KXIH.rst
new file mode 100644 (file)
index 0000000..dc3de2c
--- /dev/null
@@ -0,0 +1 @@
+Document how passing coroutines to asyncio.wait() can be confusing.