From b59b7a50eaadd83b38b8f77a1e41d7386bfc466d Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 24 Sep 2018 12:47:19 -0400 Subject: [PATCH 1/3] bpo-34790: Document how passing coroutines to asyncio.wait() can be confusing --- Doc/library/asyncio-task.rst | 37 +++++++++++++++++-- .../2018-09-24-12-47-08.bpo-34790.G2KXIH.rst | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2018-09-24-12-47-08.bpo-34790.G2KXIH.rst diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index e995fb6391adb6..a88a01fd4a8d0d 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -472,14 +472,20 @@ Waiting Primitives return_when=ALL_COMPLETED) Run :ref:`awaitable objects ` 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. Although it is + :ref:`not recommended ` to pass + coroutine objects to ``wait()`` directly. 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,32 @@ 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()`` wraps coroutines into 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. .. 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 index 00000000000000..dc3de2c7d4c809 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-09-24-12-47-08.bpo-34790.G2KXIH.rst @@ -0,0 +1 @@ +Document how passing coroutines to asyncio.wait() can be confusing. From 4308a0c25991326a980514a1304e13d915b49c54 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 24 Sep 2018 13:59:05 -0400 Subject: [PATCH 2/3] reword --- Doc/library/asyncio-task.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index a88a01fd4a8d0d..de1cb96fc061ab 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -476,9 +476,9 @@ Waiting Primitives by *return_when*. If any awaitable in *aws* is a coroutine, it is automatically - scheduled as a Task. Although it is - :ref:`not recommended ` to pass - coroutine objects to ``wait()`` directly. + scheduled as a Task. Although passing coroutines objects to + ``wait()`` directly is deprecated as it leads to + :ref:`confusing behavior `. Returns two sets of Tasks/Futures: ``(done, pending)``. @@ -523,7 +523,7 @@ Waiting Primitives .. _asyncio_example_wait_coroutine: .. note:: - ``wait()`` wraps coroutines into Tasks automatically and later + ``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:: @@ -547,6 +547,9 @@ Waiting Primitives 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) From f259492ea7e77b3862448ef56da99b52fd649298 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Tue, 25 Sep 2018 14:45:09 -0400 Subject: [PATCH 3/3] Fix per review --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index de1cb96fc061ab..bb693d7a647582 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -476,7 +476,7 @@ Waiting Primitives by *return_when*. If any awaitable in *aws* is a coroutine, it is automatically - scheduled as a Task. Although passing coroutines objects to + scheduled as a Task. Passing coroutines objects to ``wait()`` directly is deprecated as it leads to :ref:`confusing behavior `.