-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
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 all commits
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
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 |
---|---|---|
@@ -0,0 +1,121 @@ | ||
.. currentmodule:: asyncio | ||
|
||
|
||
======= | ||
Runners | ||
======= | ||
|
||
**Source code:** :source:`Lib/asyncio/runners.py` | ||
|
||
|
||
This section outlines high-level asyncio primitives to run asyncio code. | ||
|
||
They are built on top of an :ref:`event loop <asyncio-event-loop>` with the aim | ||
to simplify async code usage for common wide-spread scenarios. | ||
|
||
.. contents:: | ||
:depth: 1 | ||
:local: | ||
|
||
|
||
|
||
Running an asyncio Program | ||
========================== | ||
|
||
.. function:: run(coro, *, debug=None) | ||
|
||
Execute the :term:`coroutine` *coro* and return the result. | ||
|
||
This function runs the passed coroutine, taking care of | ||
managing the asyncio event loop, *finalizing asynchronous | ||
generators*, and closing the threadpool. | ||
|
||
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 rewritten with the runner usage:: | ||
|
||
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 default context is used if ``None``. | ||
|
||
This function cannot be called when another asyncio event loop is | ||
running in the same thread. | ||
|
||
.. method:: close() | ||
|
||
Close the runner. | ||
|
||
Finalize asynchronous generators, shutdown default executor, close the event loop | ||
and release embedded :class:`contextvars.Context`. | ||
|
||
.. method:: get_loop() | ||
|
||
Return the event loop associated with the runner instance. | ||
|
||
.. note:: | ||
|
||
:class:`Runner` uses the lazy initialization strategy, its constructor doesn't | ||
initialize underlying low-level structures. | ||
|
||
Embedded *loop* and *context* are created at the :keyword:`with` body entering | ||
or the first call of :meth:`run` or :meth:`get_loop`. |
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
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
Oops, something went wrong.
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.