Skip to content

Commit

Permalink
bpo-33649: Edit asyncio eventloop doc - second pass (pythonGH-9233)
Browse files Browse the repository at this point in the history
  • Loading branch information
willingc authored and 1st1 committed Sep 13, 2018
1 parent e1a34ce commit 5b7cbd6
Showing 1 changed file with 68 additions and 62 deletions.
130 changes: 68 additions & 62 deletions Doc/library/asyncio-eventloop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ Event Loop

.. 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
IO operations, run subprocesses, etc.
IO operations, and run subprocesses.

In general, it is *not recommended* to use event loops directly at
the application-level asyncio code. They should only be accessed
in low-level code in libraries and frameworks.

High-level asyncio applications should not need to work with event
loops and should use the :func:`asyncio.run` function to initialize
and run asynchronous code.
Application developers will typically use high-level asyncio functions
to interact with the event loop. In general, high-level asyncio applications
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
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

Expand All @@ -42,13 +42,13 @@ an event loop:
been called, asyncio will create a new event loop and set it as the
current one.

Because this function has a rather complex behavior (especially
when custom event loop policies are in use), it is recommended
to use the :func:`get_running_loop` function in coroutines and
callbacks instead.
Because this function has rather complex behavior (especially
when custom event loop policies are in use), using the
:func:`get_running_loop` function is preferred to :func:`get_event_loop`
in coroutines and callbacks.

Consider also using the :func:`asyncio.run` function instead of
manually creating and closing an event loop.
Consider also using the :func:`asyncio.run` function instead of using
lower level functions to manually create and close an event loop.

.. function:: set_event_loop(loop)

Expand All @@ -67,14 +67,14 @@ and :func:`new_event_loop` functions can be altered by

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;

* The `Callback Handles`_ section documents the :class:`Handle` and
:class:`TimerHandle`, instances of which are returned from functions
:meth:`loop.call_soon`, :meth:`loop.call_later`, etc;
:class:`TimerHandle`, instances which are returned from functions, such
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`;

* The `Event Loops Implementations`_ section documents the
Expand All @@ -89,7 +89,7 @@ This documentation page contains the following sections:
Event Loop Methods
==================

Event loops provide the following **low-level** APIs:
Event loops have **low-level** APIs for the following:

.. contents::
:depth: 1
Expand Down Expand Up @@ -120,8 +120,8 @@ Running and stopping the loop

If :meth:`stop` is called while :meth:`run_forever` is running,
the loop will run the current batch of callbacks and then exit.
Note that callbacks scheduled by callbacks will not run in that
case; they will run the next time :meth:`run_forever` or
Note that callbacks scheduled by callbacks will not run in this
case; instead, they will run the next time :meth:`run_forever` or
:meth:`run_until_complete` is called.

.. method:: loop.stop()
Expand All @@ -140,7 +140,7 @@ Running and stopping the 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.

This method clears all queues and shuts down the executor, but does
Expand All @@ -154,8 +154,9 @@ Running and stopping the loop
Schedule all currently open :term:`asynchronous generator` objects to
close with an :meth:`~agen.aclose()` call. After calling this method,
the event loop will issue a warning if a new asynchronous generator
is iterated. Should be used to reliably finalize all scheduled
asynchronous generators, e.g.:
is iterated. This should be used to reliably finalize all scheduled
asynchronous generators, e.g.::


try:
loop.run_forever()
Expand All @@ -173,7 +174,7 @@ Scheduling callbacks

.. 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.

Callbacks are called in the order in which they are registered.
Expand All @@ -184,7 +185,9 @@ Scheduling callbacks
The current context is used when no *context* is provided.

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)

Expand All @@ -200,11 +203,11 @@ Scheduling callbacks

.. 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`,
e.g.::

# will schedule "print("Hello", flush=True)":
# will schedule "print("Hello", flush=True)"
loop.call_soon(
functools.partial(print, "Hello", flush=True))

Expand Down Expand Up @@ -232,7 +235,7 @@ clocks to track time.
be used to cancel the callback.

*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.

The optional positional *args* will be passed to the callback when
Expand Down Expand Up @@ -284,8 +287,8 @@ Creating Futures and Tasks

Create an :class:`asyncio.Future` object attached to the event loop.

This is the preferred way to create Futures in asyncio, that lets
third-party event loops to provide alternative implementations of
This is the preferred way to create Futures in asyncio. This lets
third-party event loops provide alternative implementations of
the Future object (with better performance or instrumentation).

.. versionadded:: 3.5.2
Expand Down Expand Up @@ -397,7 +400,7 @@ Opening network connections

* *local_addr*, if given, is a ``(local_host, local_port)`` tuple used
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
to wait for the SSL handshake to complete before aborting the connection.
Expand Down Expand Up @@ -532,16 +535,17 @@ Creating network servers

Arguments:

* The *host* parameter can be a string, in that case the TCP server is
bound to *host* and *port*. The *host* parameter can also be a sequence
of strings and in that case the TCP server is bound to all hosts of the
sequence. If *host* is an empty string or ``None``, all interfaces are
assumed and a list of multiple sockets will be returned (most likely one
for IPv4 and another one for IPv6).
* The *host* parameter can be set to several types which determine behavior:
- If *host* is a string, the TCP server is bound to *host* and *port*.
- if *host* is a sequence of strings, the TCP server is bound to all
hosts of the sequence.
- If *host* is an empty string or ``None``, all interfaces are
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
: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`).

* *flags* is a bitmask for :meth:`getaddrinfo`.
Expand Down Expand Up @@ -721,24 +725,24 @@ Watching file descriptors

.. 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.

.. 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)

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.

Use :func:`functools.partial` :ref:`to pass keywords
<asyncio-pass-keywords>` to *func*.

.. 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
for some limitations of these methods.
Expand All @@ -747,10 +751,10 @@ for some limitations of these methods.
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`
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
convenient.

Expand All @@ -765,8 +769,8 @@ convenient.
The socket *sock* must be non-blocking.

.. versionchanged:: 3.7
Even though the method was always documented as a coroutine
method, before Python 3.7 it returned a :class:`Future`.
Even though this method was always documented as a coroutine
method, releases before Python 3.7 returned a :class:`Future`.
Since Python 3.7 this is an ``async def`` method.

.. coroutinemethod:: loop.sock_recv_into(sock, buf)
Expand All @@ -785,10 +789,11 @@ convenient.
Send data to the socket. Asynchronous version of
:meth:`socket.sendall() <socket.socket.sendall>`.

This method continues to send data from *data* until either all data has
been sent or an error occurs. ``None`` is returned on success. On error,
an exception is raised, and there is no way to determine how much data, if
any, was successfully processed by the receiving end of the connection.
This method continues to send data from *data* to the socket until either
all data in *data* has been sent or an error occurs. ``None`` is returned
on success. On error, an exception is raised. Additionally, there is no way
to determine how much data, if any, was successfully processed by the
receiving end of the connection.

The socket *sock* must be non-blocking.

Expand Down Expand Up @@ -860,7 +865,7 @@ convenient.
<io.IOBase.tell>` can be used to figure out the number of bytes
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
(e.g. Windows or SSL socket on Unix).

Expand Down Expand Up @@ -927,7 +932,7 @@ Working with pipes
.. note::

:class:`SelectorEventLoop` does not support the above methods on
Windows. Use :class:`ProactorEventLoop` instead.
Windows. Use :class:`ProactorEventLoop` instead for Windows.

.. seealso::

Expand Down Expand Up @@ -1028,8 +1033,8 @@ Allows customizing how exceptions are handled in the event loop.
Default exception handler.

This is called when an exception occurs and no exception
handler is set, and can be called by a custom exception
handler that wants to defer to the default behavior.
handler is set. This can be called by a custom exception
handler that wants to defer to the default handler behavior.

*context* parameter has the same meaning as in
:meth:`call_exception_handler`.
Expand All @@ -1051,7 +1056,7 @@ Allows customizing how exceptions are handled in the event loop.

.. 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
:meth:`set_exception_handler()` method.

Expand Down Expand Up @@ -1104,7 +1109,7 @@ async/await code consider using high-level convenient
:ref:`filesystem encoding <filesystem-encoding>`.

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.

This is similar to the standard library :class:`subprocess.Popen`
Expand Down Expand Up @@ -1238,8 +1243,7 @@ Do not instantiate the class directly.
async with srv:
# some code

# At this point, srv is closed and no longer accepts new
connections.
# At this point, srv is closed and no longer accepts new connections.


.. versionchanged:: 3.7
Expand Down Expand Up @@ -1408,6 +1412,7 @@ event loop::
import asyncio

def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()

Expand Down Expand Up @@ -1478,6 +1483,7 @@ Wait until a file descriptor received some data using the

# Create a pair of connected file descriptors
rsock, wsock = socketpair()

loop = asyncio.get_event_loop()

def reader():
Expand All @@ -1500,7 +1506,7 @@ Wait until a file descriptor received some data using the
# Run the event loop
loop.run_forever()
finally:
# We are done, close sockets and the event loop
# We are done. Close sockets and the event loop.
rsock.close()
wsock.close()
loop.close()
Expand All @@ -1519,7 +1525,7 @@ Wait until a file descriptor received some data using the
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`
using the :meth:`loop.add_signal_handler` method::
Expand Down

0 comments on commit 5b7cbd6

Please sign in to comment.