From a344c30dfb2286c4bb2e3230786fd2f228f240d6 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Tue, 11 Sep 2018 14:01:06 -0700 Subject: [PATCH 1/5] Polish doc as part of asyncio doc rewrite Signed-off-by: Carol Willing --- Doc/library/asyncio-dev.rst | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index cb574c308ad1bd3..fdf1709ee491d6b 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -98,9 +98,11 @@ Concurrency and multithreading An event loop runs in a thread (typically the main thread) and executes all callbacks and tasks in its thread. While a task is running in the -event loop, no other task is running in the same thread. When a task -executes an ``await`` expression, the task gets suspended and the -event loop executes the next task. +event loop, no other tasks may run in the same thread. When a task +executes an ``await`` expression, the running task gets suspended, and the +event loop executes the next task. Prior to suspending the task, the awaiting +chain is checked, and if the chain ends with a future, the running task is +not suspended. To schedule a callback from a different thread, the :meth:`loop.call_soon_threadsafe` method should be used. Example:: @@ -123,9 +125,9 @@ To schedule a coroutine object from a different thread, the future = asyncio.run_coroutine_threadsafe(coro_func(), loop) result = future.result(timeout) # Wait for the result with a timeout -The :meth:`loop.run_in_executor` method can be used with a thread pool -executor to execute a callback in different thread to not block the thread of -the event loop. +The :meth:`loop.run_in_executor` method can be used with a +:class:`concurrent.futures.ThreadPoolExecutor` to execute a callback in +different thread so as not to block the event loop's main thread. .. seealso:: @@ -183,9 +185,10 @@ Detect coroutine objects never scheduled ---------------------------------------- When a coroutine function is called and its result is not passed to -:func:`ensure_future` or to the :meth:`loop.create_task` method, -the execution of the coroutine object will never be scheduled which is -probably a bug. :ref:`Enable the debug mode of asyncio ` +:func:`ensure_future`, :meth:`asyncio.create_task`, or to the +:meth:`loop.create_task` method, the execution of the coroutine object will +never be scheduled which is probably a bug. +:ref:`Enable the debug mode of asyncio ` to :ref:`log a warning ` to detect it. Example with the bug:: @@ -204,8 +207,9 @@ Output in debug mode:: File "test.py", line 7, in test() -The fix is to call the :func:`ensure_future` function or the -:meth:`loop.create_task` method with the coroutine object. +The fix is to call the :func:`ensure_future` function, +:meth:`asyncio.create_task`, or the :meth:`loop.create_task` method with the +coroutine object. .. seealso:: @@ -281,6 +285,7 @@ coroutine in another coroutine and use classic try/except:: loop.close() Another option is to use the :meth:`loop.run_until_complete` +(or alternatively, the provisional :meth:`asyncio.run`) function:: task = asyncio.ensure_future(bug()) From fb64f8ccb5577c036d4739949713aa253cf3b551 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Tue, 11 Sep 2018 15:48:31 -0700 Subject: [PATCH 2/5] add @1st1 review suggestion --- Doc/library/asyncio-dev.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index fdf1709ee491d6b..4401cfc58543fc5 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -185,10 +185,10 @@ Detect coroutine objects never scheduled ---------------------------------------- When a coroutine function is called and its result is not passed to -:func:`ensure_future`, :meth:`asyncio.create_task`, or to the -:meth:`loop.create_task` method, the execution of the coroutine object will -never be scheduled which is probably a bug. -:ref:`Enable the debug mode of asyncio ` +:meth:`asyncio.create_task` the execution of the coroutine object will +never be scheduled which is probably a bug. Using `asyncio.create_task` is +preferred to the low level :func:`ensure_future` and :meth:`loop.create_task` +methods. :ref:`Enable the debug mode of asyncio ` to :ref:`log a warning ` to detect it. Example with the bug:: @@ -207,9 +207,9 @@ Output in debug mode:: File "test.py", line 7, in test() -The fix is to call the :func:`ensure_future` function, -:meth:`asyncio.create_task`, or the :meth:`loop.create_task` method with the -coroutine object. +The fix is to call the :meth:`asyncio.create_task` function. Using +`asyncio.create_task` is preferred to the low level :func:`ensure_future` and +:meth:`loop.create_task` methods. .. seealso:: From 77e7b1f613150e0c6679bdcd715eba38a3bd5c56 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Tue, 11 Sep 2018 16:36:56 -0700 Subject: [PATCH 3/5] update text per @1st1 review and the related code example --- Doc/library/asyncio-dev.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 4401cfc58543fc5..e796a7000797866 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -284,13 +284,11 @@ coroutine in another coroutine and use classic try/except:: loop.run_forever() loop.close() -Another option is to use the :meth:`loop.run_until_complete` -(or alternatively, the provisional :meth:`asyncio.run`) -function:: +Another option is to use the :meth:`asyncio.run` function:: task = asyncio.ensure_future(bug()) try: - loop.run_until_complete(task) + asyncio.run(task) except Exception: print("exception consumed") From 4f879a003c54c295eb10cc8bad651025c6f62ef0 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Tue, 11 Sep 2018 16:44:37 -0700 Subject: [PATCH 4/5] fix code example --- Doc/library/asyncio-dev.rst | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index e796a7000797866..219bc14ce9d224b 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -286,11 +286,7 @@ coroutine in another coroutine and use classic try/except:: Another option is to use the :meth:`asyncio.run` function:: - task = asyncio.ensure_future(bug()) - try: - asyncio.run(task) - except Exception: - print("exception consumed") + asyncio.run(bug()) .. seealso:: From c73f42ca6f0f0e8ff59339191691c6f075c3c720 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Wed, 12 Sep 2018 14:24:40 -0700 Subject: [PATCH 5/5] fix lint typos --- Doc/library/asyncio-dev.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 219bc14ce9d224b..e4986ba5eb26576 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -126,7 +126,7 @@ To schedule a coroutine object from a different thread, the result = future.result(timeout) # Wait for the result with a timeout The :meth:`loop.run_in_executor` method can be used with a -:class:`concurrent.futures.ThreadPoolExecutor` to execute a callback in +:class:`concurrent.futures.ThreadPoolExecutor` to execute a callback in different thread so as not to block the event loop's main thread. .. seealso:: @@ -186,8 +186,8 @@ Detect coroutine objects never scheduled When a coroutine function is called and its result is not passed to :meth:`asyncio.create_task` the execution of the coroutine object will -never be scheduled which is probably a bug. Using `asyncio.create_task` is -preferred to the low level :func:`ensure_future` and :meth:`loop.create_task` +never be scheduled which is probably a bug. Using ``asyncio.create_task`` is +preferred to the low level :func:`ensure_future` and :meth:`loop.create_task` methods. :ref:`Enable the debug mode of asyncio ` to :ref:`log a warning ` to detect it. @@ -207,8 +207,8 @@ Output in debug mode:: File "test.py", line 7, in test() -The fix is to call the :meth:`asyncio.create_task` function. Using -`asyncio.create_task` is preferred to the low level :func:`ensure_future` and +The fix is to call the :meth:`asyncio.create_task` function. Using +``asyncio.create_task`` is preferred to the low level :func:`ensure_future` and :meth:`loop.create_task` methods. .. seealso::