-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
bpo-47062: Implement asyncio.Runner context manager #31799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
61f10d0
Implement Runner class
asvetlov d471799
Add get_loop() / new_loop() methods
asvetlov c68ba85
Clarify
asvetlov d530481
Add tests
asvetlov 6ee7c9a
Add a comment
asvetlov e15d70b
Adopt IsolatedAsyncioTestCase to use Runner
asvetlov 5c7a669
Merge branch 'main' into asyncio-runner
asvetlov d41988d
Merge branch 'main' into asyncio-runner
asvetlov 8014227
Add docs sketch
asvetlov 98e39db
Merge branch 'main' into asyncio-runner
asvetlov 98e7a22
Add context arg to Runner.run()
asvetlov f4cd673
Work on docs
asvetlov 1764045
Merge branch 'main' into asyncio-runner
asvetlov a443b37
Work on
asvetlov e6be8f7
Improve docs
asvetlov b1dfe4f
Add NEWS
asvetlov 759f72a
Drop not related file
asvetlov f47d66a
Fix doc
asvetlov 546440b
Update Lib/asyncio/runners.py
asvetlov 6935f7d
Update Doc/library/asyncio-runner.rst
asvetlov 9b9a004
Update Lib/asyncio/runners.py
asvetlov b0c5b8c
Improve wording
asvetlov 599c9db
Add a test for double 'with' usage
asvetlov b0da74b
Improve tests
asvetlov 04cfff9
Work on
asvetlov 8753465
Merge branch 'main' into asyncio-runner
asvetlov 674ad4e
Lazy init version
asvetlov 7cd5430
Tune
asvetlov dd28ef7
Drop explicit get_context() function, asyncio.Task has no it also
asvetlov 5e13b2e
Add docs for .close() method
asvetlov c0b999d
Add better error message for recursive run() call
asvetlov 4937cd0
Add a note
asvetlov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Improve docs
- Loading branch information
commit e6be8f72e4c8be69b72999c4cbb375efca63b029
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,109 @@ | ||
.. currentmodule:: asyncio | ||
|
||
|
||
====== | ||
Runner | ||
====== | ||
======= | ||
Runners | ||
======= | ||
|
||
**Source code:** :source:`Lib/asyncio/runners.py` | ||
|
||
------------------------------------ | ||
|
||
This section outlines high-level asyncio primitives to run asyncio code. | ||
|
||
:func:`asyncio.run` provides a convinient very high-level API for running asyncio code. | ||
They are built on top of :ref:`event loop <asyncio-event-loop>` with the aim to simplify | ||
async code usage for common wide-spread scenarion. | ||
|
||
It is the preferred approach that satisfies almost all use cases. | ||
.. contents:: | ||
:depth: 1 | ||
:local: | ||
|
||
Sometimes several top-level async calls are needed in the same loop and contextvars | ||
context instead of the single ``main()`` call provided by :func:`asyncio.run`. | ||
|
||
The *Runner* context manager can be used for such things: | ||
|
||
.. code:: python | ||
Running an asyncio Program | ||
========================== | ||
|
||
with asyncio.Runner() as runner: | ||
runner.run(func1()) | ||
runner.run(func2()) | ||
.. function:: run(coro, *, debug=None) | ||
|
||
On the :class:`~asyncio.Runner` instantiation the new event loop is created. | ||
Execute the :term:`coroutine` *coro* and return the result. | ||
|
||
All :meth:`~asyncio.Runner.run` calls share the same :class:`~contextvars.Context` and | ||
internal :class:`~asyncio.loop`. | ||
This function runs the passed coroutine, taking care of | ||
managing the asyncio event loop, *finalizing asynchronous | ||
generators*, and closing the threadpool. | ||
|
||
On the exit of :keyword:`with` block all background tasks are cancelled, the embedded | ||
loop is closing. | ||
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. ``False`` disables | ||
debug mode explicitly. ``None`` is used to respect the global | ||
:ref:`asyncio-debug-mode` settings. | ||
|
||
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`. | ||
|
||
.. versionchanged:: 3.10 | ||
|
||
*debug* is ``None`` by default to respect the global debug mode settings. | ||
|
||
|
||
Runner context manager | ||
====================== | ||
|
||
.. class:: Runner(*, debug=None, factory=None) | ||
|
||
A context manager that simplifies *multiple* async function calls in the same | ||
context. | ||
|
||
Sometimes several top-level async functions should be called in the same :ref:`event | ||
loop <asyncio-event-loop>` and :class:`contextvars.Context`. | ||
|
||
If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables | ||
debug mode explicitly. ``None`` is used to respect the global | ||
:ref:`asyncio-debug-mode` settings. | ||
|
||
*factory* could be used for overriding the loop creation. | ||
:func:`asyncio.new_event_loop` is used if ``None``. | ||
|
||
Basically, :func:`asyncio.run()` example can be revealed with the runner usage: | ||
asvetlov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
.. block:: python | ||
|
||
async def main(): | ||
await asyncio.sleep(1) | ||
print('hello') | ||
|
||
with asyncio.Runner() as runner: | ||
runner.run(main()) | ||
|
||
.. versionadded:: 3.11 | ||
|
||
.. method:: run(coro, *, context=None) | ||
|
||
Run a :term:`coroutine <coroutine>` *coro* in the embedded loop. | ||
|
||
Return the coroutine's result or raise its exception. | ||
|
||
An optional keyword-only *context* argument allows specifying a | ||
custom :class:`contextvars.Context` for the *coro* to run in. | ||
The runner's context is used if ``None``. | ||
|
||
enter | ||
Usually, | ||
.. method:: get_loop() | ||
|
||
.. rubric:: Preface | ||
Return the event loop associated with the runner instance. | ||
|
||
The event loop is the core of every asyncio application. | ||
Event loops run asynchronous tasks and callbacks, perform network | ||
IO operations, and run subprocesses. | ||
.. method:: get_context() | ||
|
||
Application developers should typically use the high-level asyncio functions, | ||
such as :func:`asyncio.run`, and should rarely need to reference the loop | ||
object or call its methods. This section is intended mostly for authors | ||
of lower-level code, libraries, and frameworks, who need finer control over | ||
the event loop behavior. | ||
Return the :class:`contextvars.Context` associated with the runner object. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.