Kaydet (Commit) 5b7cbd60 authored tarafından Carol Willing's avatar Carol Willing Kaydeden (comit) Yury Selivanov

bpo-33649: Edit asyncio eventloop doc - second pass (GH-9233)

üst e1a34ceb
...@@ -8,18 +8,18 @@ Event Loop ...@@ -8,18 +8,18 @@ Event Loop
.. rubric:: Preface .. rubric:: Preface
An event loop is the central component of every asyncio application. The event loop is a central component of every asyncio application.
Event loops run asynchronous tasks and callbacks, perform network Event loops run asynchronous tasks and callbacks, perform network
IO operations, run subprocesses, etc. IO operations, and run subprocesses.
In general, it is *not recommended* to use event loops directly at Application developers will typically use high-level asyncio functions
the application-level asyncio code. They should only be accessed to interact with the event loop. In general, high-level asyncio applications
in low-level code in libraries and frameworks. should not need to work directly with event loops and, instead, should use
the :func:`asyncio.run` function to initialize, manage the event loop, and
High-level asyncio applications should not need to work with event run asynchronous code.
loops and should use the :func:`asyncio.run` function to initialize
and run asynchronous code.
Alternatively, developers of low-level code, such as libraries and
framework, may need access to the event loop.
.. rubric:: Accessing Event Loop .. rubric:: Accessing Event Loop
...@@ -42,13 +42,13 @@ an event loop: ...@@ -42,13 +42,13 @@ an event loop:
been called, asyncio will create a new event loop and set it as the been called, asyncio will create a new event loop and set it as the
current one. current one.
Because this function has a rather complex behavior (especially Because this function has rather complex behavior (especially
when custom event loop policies are in use), it is recommended when custom event loop policies are in use), using the
to use the :func:`get_running_loop` function in coroutines and :func:`get_running_loop` function is preferred to :func:`get_event_loop`
callbacks instead. in coroutines and callbacks.
Consider also using the :func:`asyncio.run` function instead of Consider also using the :func:`asyncio.run` function instead of using
manually creating and closing an event loop. lower level functions to manually create and close an event loop.
.. function:: set_event_loop(loop) .. function:: set_event_loop(loop)
...@@ -67,14 +67,14 @@ and :func:`new_event_loop` functions can be altered by ...@@ -67,14 +67,14 @@ and :func:`new_event_loop` functions can be altered by
This documentation page contains the following sections: This documentation page contains the following sections:
* The `Event Loop Methods`_ section is a reference documentation of * The `Event Loop Methods`_ section is the reference documentation of
event loop APIs; event loop APIs;
* The `Callback Handles`_ section documents the :class:`Handle` and * The `Callback Handles`_ section documents the :class:`Handle` and
:class:`TimerHandle`, instances of which are returned from functions :class:`TimerHandle`, instances which are returned from functions, such
:meth:`loop.call_soon`, :meth:`loop.call_later`, etc; as :meth:`loop.call_soon` and :meth:`loop.call_later`;
* The `Server Objects`_ sections documents types returned from * The `Server Objects`_ sections document types returned from
event loop methods like :meth:`loop.create_server`; event loop methods like :meth:`loop.create_server`;
* The `Event Loops Implementations`_ section documents the * The `Event Loops Implementations`_ section documents the
...@@ -89,7 +89,7 @@ This documentation page contains the following sections: ...@@ -89,7 +89,7 @@ This documentation page contains the following sections:
Event Loop Methods Event Loop Methods
================== ==================
Event loops provide the following **low-level** APIs: Event loops have **low-level** APIs for the following:
.. contents:: .. contents::
:depth: 1 :depth: 1
...@@ -120,8 +120,8 @@ Running and stopping the loop ...@@ -120,8 +120,8 @@ Running and stopping the loop
If :meth:`stop` is called while :meth:`run_forever` is running, If :meth:`stop` is called while :meth:`run_forever` is running,
the loop will run the current batch of callbacks and then exit. the loop will run the current batch of callbacks and then exit.
Note that callbacks scheduled by callbacks will not run in that Note that callbacks scheduled by callbacks will not run in this
case; they will run the next time :meth:`run_forever` or case; instead, they will run the next time :meth:`run_forever` or
:meth:`run_until_complete` is called. :meth:`run_until_complete` is called.
.. method:: loop.stop() .. method:: loop.stop()
...@@ -140,7 +140,7 @@ Running and stopping the loop ...@@ -140,7 +140,7 @@ Running and stopping the loop
Close the event loop. Close the event loop.
The loop cannot not be running when this function is called. The loop must be running when this function is called.
Any pending callbacks will be discarded. Any pending callbacks will be discarded.
This method clears all queues and shuts down the executor, but does This method clears all queues and shuts down the executor, but does
...@@ -154,8 +154,9 @@ Running and stopping the loop ...@@ -154,8 +154,9 @@ Running and stopping the loop
Schedule all currently open :term:`asynchronous generator` objects to Schedule all currently open :term:`asynchronous generator` objects to
close with an :meth:`~agen.aclose()` call. After calling this method, close with an :meth:`~agen.aclose()` call. After calling this method,
the event loop will issue a warning if a new asynchronous generator the event loop will issue a warning if a new asynchronous generator
is iterated. Should be used to reliably finalize all scheduled is iterated. This should be used to reliably finalize all scheduled
asynchronous generators, e.g.: asynchronous generators, e.g.::
try: try:
loop.run_forever() loop.run_forever()
...@@ -173,7 +174,7 @@ Scheduling callbacks ...@@ -173,7 +174,7 @@ Scheduling callbacks
.. method:: loop.call_soon(callback, *args, context=None) .. method:: loop.call_soon(callback, *args, context=None)
Schedule *callback* to be called with *args* arguments at Schedule a *callback* to be called with *args* arguments at
the next iteration of the event loop. the next iteration of the event loop.
Callbacks are called in the order in which they are registered. Callbacks are called in the order in which they are registered.
...@@ -184,7 +185,9 @@ Scheduling callbacks ...@@ -184,7 +185,9 @@ Scheduling callbacks
The current context is used when no *context* is provided. The current context is used when no *context* is provided.
An instance of :class:`asyncio.Handle` is returned, which can be An instance of :class:`asyncio.Handle` is returned, which can be
used to cancel the callback. used later to cancel the callback.
This method is not thread-safe.
.. method:: loop.call_soon_threadsafe(callback, *args, context=None) .. method:: loop.call_soon_threadsafe(callback, *args, context=None)
...@@ -200,11 +203,11 @@ Scheduling callbacks ...@@ -200,11 +203,11 @@ Scheduling callbacks
.. note:: .. note::
Most :mod:`asyncio` scheduling functions don't allow to pass Most :mod:`asyncio` scheduling functions don't allow passing
keyword arguments. To do that, use :func:`functools.partial`, keyword arguments. To do that, use :func:`functools.partial`,
e.g.:: e.g.::
# will schedule "print("Hello", flush=True)": # will schedule "print("Hello", flush=True)"
loop.call_soon( loop.call_soon(
functools.partial(print, "Hello", flush=True)) functools.partial(print, "Hello", flush=True))
...@@ -232,7 +235,7 @@ clocks to track time. ...@@ -232,7 +235,7 @@ clocks to track time.
be used to cancel the callback. be used to cancel the callback.
*callback* will be called exactly once. If two callbacks are *callback* will be called exactly once. If two callbacks are
scheduled for exactly the same time, it is undefined which will scheduled for exactly the same time, it is undefined which one will
be called first. be called first.
The optional positional *args* will be passed to the callback when The optional positional *args* will be passed to the callback when
...@@ -284,8 +287,8 @@ Creating Futures and Tasks ...@@ -284,8 +287,8 @@ Creating Futures and Tasks
Create an :class:`asyncio.Future` object attached to the event loop. Create an :class:`asyncio.Future` object attached to the event loop.
This is the preferred way to create Futures in asyncio, that lets This is the preferred way to create Futures in asyncio. This lets
third-party event loops to provide alternative implementations of third-party event loops provide alternative implementations of
the Future object (with better performance or instrumentation). the Future object (with better performance or instrumentation).
.. versionadded:: 3.5.2 .. versionadded:: 3.5.2
...@@ -397,7 +400,7 @@ Opening network connections ...@@ -397,7 +400,7 @@ Opening network connections
* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
to bind the socket to locally. The *local_host* and *local_port* to bind the socket to locally. The *local_host* and *local_port*
are looked up using getaddrinfo(), similarly to *host* and *port*. are looked up using ``getaddrinfo()``, similarly to *host* and *port*.
* *ssl_handshake_timeout* is (for an SSL connection) the time in seconds * *ssl_handshake_timeout* is (for an SSL connection) the time in seconds
to wait for the SSL handshake to complete before aborting the connection. to wait for the SSL handshake to complete before aborting the connection.
...@@ -532,16 +535,17 @@ Creating network servers ...@@ -532,16 +535,17 @@ Creating network servers
Arguments: Arguments:
* The *host* parameter can be a string, in that case the TCP server is * The *host* parameter can be set to several types which determine behavior:
bound to *host* and *port*. The *host* parameter can also be a sequence - If *host* is a string, the TCP server is bound to *host* and *port*.
of strings and in that case the TCP server is bound to all hosts of the - if *host* is a sequence of strings, the TCP server is bound to all
sequence. If *host* is an empty string or ``None``, all interfaces are hosts of the sequence.
assumed and a list of multiple sockets will be returned (most likely one - If *host* is an empty string or ``None``, all interfaces are
for IPv4 and another one for IPv6). assumed and a list of multiple sockets will be returned (most likely
one for IPv4 and another one for IPv6).
* *family* can be set to either :data:`socket.AF_INET` or * *family* can be set to either :data:`socket.AF_INET` or
:data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6.
If not set it will be determined from host name If not set, the *family* will be determined from host name
(defaults to :data:`~socket.AF_UNSPEC`). (defaults to :data:`~socket.AF_UNSPEC`).
* *flags* is a bitmask for :meth:`getaddrinfo`. * *flags* is a bitmask for :meth:`getaddrinfo`.
...@@ -721,16 +725,16 @@ Watching file descriptors ...@@ -721,16 +725,16 @@ Watching file descriptors
.. method:: loop.add_reader(fd, callback, \*args) .. method:: loop.add_reader(fd, callback, \*args)
Start watching the file descriptor for read availability and Start watching the file descriptor *fd* for read availability and
call the *callback* with specified arguments. call the *callback* with specified arguments.
.. method:: loop.remove_reader(fd) .. method:: loop.remove_reader(fd)
Stop watching the file descriptor for read availability. Stop watching the file descriptor *fd* for read availability.
.. method:: loop.add_writer(fd, callback, \*args) .. method:: loop.add_writer(fd, callback, \*args)
Start watching the file descriptor for write availability and then Start watching the file descriptor *fd* for write availability and then
call the *callback* with specified arguments. call the *callback* with specified arguments.
Use :func:`functools.partial` :ref:`to pass keywords Use :func:`functools.partial` :ref:`to pass keywords
...@@ -738,7 +742,7 @@ Watching file descriptors ...@@ -738,7 +742,7 @@ Watching file descriptors
.. method:: loop.remove_writer(fd) .. method:: loop.remove_writer(fd)
Stop watching the file descriptor for write availability. Stop watching the file descriptor *fd* for write availability.
See also :ref:`Platform Support <asyncio-platform-support>` section See also :ref:`Platform Support <asyncio-platform-support>` section
for some limitations of these methods. for some limitations of these methods.
...@@ -747,10 +751,10 @@ for some limitations of these methods. ...@@ -747,10 +751,10 @@ for some limitations of these methods.
Working with socket objects directly Working with socket objects directly
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In general, protocols implementations that use transport-based APIs In general, protocol implementations that use transport-based APIs
such as :meth:`loop.create_connection` and :meth:`loop.create_server` such as :meth:`loop.create_connection` and :meth:`loop.create_server`
are faster than implementations that work with sockets directly. are faster than implementations that work with sockets directly.
However, there are use cases when performance is not critical and However, there are some use cases when performance is not critical, and
working with :class:`~socket.socket` objects directly is more working with :class:`~socket.socket` objects directly is more
convenient. convenient.
...@@ -765,8 +769,8 @@ convenient. ...@@ -765,8 +769,8 @@ convenient.
The socket *sock* must be non-blocking. The socket *sock* must be non-blocking.
.. versionchanged:: 3.7 .. versionchanged:: 3.7
Even though the method was always documented as a coroutine Even though this method was always documented as a coroutine
method, before Python 3.7 it returned a :class:`Future`. method, releases before Python 3.7 returned a :class:`Future`.
Since Python 3.7 this is an ``async def`` method. Since Python 3.7 this is an ``async def`` method.
.. coroutinemethod:: loop.sock_recv_into(sock, buf) .. coroutinemethod:: loop.sock_recv_into(sock, buf)
...@@ -785,10 +789,11 @@ convenient. ...@@ -785,10 +789,11 @@ convenient.
Send data to the socket. Asynchronous version of Send data to the socket. Asynchronous version of
:meth:`socket.sendall() <socket.socket.sendall>`. :meth:`socket.sendall() <socket.socket.sendall>`.
This method continues to send data from *data* until either all data has This method continues to send data from *data* to the socket until either
been sent or an error occurs. ``None`` is returned on success. On error, all data in *data* has been sent or an error occurs. ``None`` is returned
an exception is raised, and there is no way to determine how much data, if on success. On error, an exception is raised. Additionally, there is no way
any, was successfully processed by the receiving end of the connection. to determine how much data, if any, was successfully processed by the
receiving end of the connection.
The socket *sock* must be non-blocking. The socket *sock* must be non-blocking.
...@@ -860,7 +865,7 @@ convenient. ...@@ -860,7 +865,7 @@ convenient.
<io.IOBase.tell>` can be used to figure out the number of bytes <io.IOBase.tell>` can be used to figure out the number of bytes
which were sent. which were sent.
*fallback* set to ``True`` makes asyncio to manually read and send *fallback*, when set to ``True``, makes asyncio manually read and send
the file when the platform does not support the sendfile syscall the file when the platform does not support the sendfile syscall
(e.g. Windows or SSL socket on Unix). (e.g. Windows or SSL socket on Unix).
...@@ -927,7 +932,7 @@ Working with pipes ...@@ -927,7 +932,7 @@ Working with pipes
.. note:: .. note::
:class:`SelectorEventLoop` does not support the above methods on :class:`SelectorEventLoop` does not support the above methods on
Windows. Use :class:`ProactorEventLoop` instead. Windows. Use :class:`ProactorEventLoop` instead for Windows.
.. seealso:: .. seealso::
...@@ -1028,8 +1033,8 @@ Allows customizing how exceptions are handled in the event loop. ...@@ -1028,8 +1033,8 @@ Allows customizing how exceptions are handled in the event loop.
Default exception handler. Default exception handler.
This is called when an exception occurs and no exception This is called when an exception occurs and no exception
handler is set, and can be called by a custom exception handler is set. This can be called by a custom exception
handler that wants to defer to the default behavior. handler that wants to defer to the default handler behavior.
*context* parameter has the same meaning as in *context* parameter has the same meaning as in
:meth:`call_exception_handler`. :meth:`call_exception_handler`.
...@@ -1051,7 +1056,7 @@ Allows customizing how exceptions are handled in the event loop. ...@@ -1051,7 +1056,7 @@ Allows customizing how exceptions are handled in the event loop.
.. note:: .. note::
Note: this method should not be overloaded in subclassed This method should not be overloaded in subclassed
event loops. For any custom exception handling, use event loops. For any custom exception handling, use
:meth:`set_exception_handler()` method. :meth:`set_exception_handler()` method.
...@@ -1104,7 +1109,7 @@ async/await code consider using high-level convenient ...@@ -1104,7 +1109,7 @@ async/await code consider using high-level convenient
:ref:`filesystem encoding <filesystem-encoding>`. :ref:`filesystem encoding <filesystem-encoding>`.
The first string specifies the program to execute, The first string specifies the program to execute,
and the remaining strings specify the arguments. Together string and the remaining strings specify the arguments. Together, string
arguments form the ``argv`` of the program. arguments form the ``argv`` of the program.
This is similar to the standard library :class:`subprocess.Popen` This is similar to the standard library :class:`subprocess.Popen`
...@@ -1238,8 +1243,7 @@ Do not instantiate the class directly. ...@@ -1238,8 +1243,7 @@ Do not instantiate the class directly.
async with srv: async with srv:
# some code # some code
# At this point, srv is closed and no longer accepts new # At this point, srv is closed and no longer accepts new connections.
connections.
.. versionchanged:: 3.7 .. versionchanged:: 3.7
...@@ -1408,6 +1412,7 @@ event loop:: ...@@ -1408,6 +1412,7 @@ event loop::
import asyncio import asyncio
def hello_world(loop): def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World') print('Hello World')
loop.stop() loop.stop()
...@@ -1478,6 +1483,7 @@ Wait until a file descriptor received some data using the ...@@ -1478,6 +1483,7 @@ Wait until a file descriptor received some data using the
# Create a pair of connected file descriptors # Create a pair of connected file descriptors
rsock, wsock = socketpair() rsock, wsock = socketpair()
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
def reader(): def reader():
...@@ -1500,7 +1506,7 @@ Wait until a file descriptor received some data using the ...@@ -1500,7 +1506,7 @@ Wait until a file descriptor received some data using the
# Run the event loop # Run the event loop
loop.run_forever() loop.run_forever()
finally: finally:
# We are done, close sockets and the event loop # We are done. Close sockets and the event loop.
rsock.close() rsock.close()
wsock.close() wsock.close()
loop.close() loop.close()
...@@ -1519,7 +1525,7 @@ Wait until a file descriptor received some data using the ...@@ -1519,7 +1525,7 @@ Wait until a file descriptor received some data using the
Set signal handlers for SIGINT and SIGTERM Set signal handlers for SIGINT and SIGTERM
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(This example only works on UNIX.) (This ``signals`` example only works on UNIX.)
Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`
using the :meth:`loop.add_signal_handler` method:: using the :meth:`loop.add_signal_handler` method::
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment