From 1fa2ec49bec50bea1847b558b883c5c904334734 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Mon, 17 Sep 2018 19:16:44 -0400 Subject: [PATCH] bpo-33649: A copy-editing pass on asyncio documentation (GH-9376) --- Doc/library/asyncio-dev.rst | 53 +++-- Doc/library/asyncio-eventloop.rst | 327 +++++++++++++++-------------- Doc/library/asyncio-exceptions.rst | 18 +- Doc/library/asyncio-platforms.rst | 12 +- Doc/library/asyncio-policy.rst | 23 +- Doc/library/asyncio-protocol.rst | 61 +++--- Doc/library/asyncio-queue.rst | 6 +- Doc/library/asyncio-stream.rst | 68 +++--- Doc/library/asyncio-subprocess.rst | 57 ++--- Doc/library/asyncio-sync.rst | 14 +- Doc/library/asyncio-task.rst | 52 ++--- Doc/library/asyncio.rst | 5 +- 12 files changed, 347 insertions(+), 349 deletions(-) diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index e815318676..5f926fceb2 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -6,7 +6,7 @@ Developing with asyncio ======================= -Asynchronous programming is different from classical "sequential" +Asynchronous programming is different from classic "sequential" programming. This page lists common mistakes and traps and explains how @@ -21,19 +21,17 @@ Debug Mode By default asyncio runs in production mode. In order to ease the development asyncio has a *debug mode*. -To enable debugging for an application: +There are several ways to enable asyncio debug mode: -* Enable the debug mode globally by setting the environment variable - :envvar:`PYTHONASYNCIODEBUG` to ``1``. +* Setting the :envvar:`PYTHONASYNCIODEBUG` environment variable to ``1``. -* Alternatively, the debug mode can be enabled by using the ``-X dev`` - command line option for Python (see the :option:`-X` option). +* Using the :option:`-X` ``dev`` Python command line option. -* Yet another way to enable the debug mode is by calling - :meth:`loop.set_debug` or by passing ``debug=True`` to - :func:`asyncio.run`. +* Passing ``debug=True`` to :func:`asyncio.run`. -In addition to enabling debug mode, consider also: +* Calling :meth:`loop.set_debug`. + +In addition to enabling the debug mode, consider also: * setting the log level of the :ref:`asyncio logger ` to :py:data:`logging.DEBUG`, for example the following snippet of code @@ -43,25 +41,25 @@ In addition to enabling debug mode, consider also: * configuring the :mod:`warnings` module to display :exc:`ResourceWarning` warnings. One way of doing that is by - using the ``-Wdefault`` command line option. + using the :option:`-W` ``default`` command line option. -In asyncio debug mode the following checks are performed: +When the debug mode is enabled: -* Log :ref:`coroutines that were not awaited - `; this mitigates the "forgotten - await" pitfall. +* asyncio checks for :ref:`coroutines that were not awaited + ` and logs them; this mitigates + the "forgotten await" pitfall. * Many non-treadsafe asyncio APIs (such as :meth:`loop.call_soon` and :meth:`loop.call_at` methods) raise an exception if they are called from a wrong thread. -* Log the execution time of the IO selector if it takes too long to - perform an IO operation. +* The execution time of the I/O selector is logged if it takes too long to + perform an I/O operation. -* Log callbacks taking longer than 100 ms to be executed. The - :attr:`loop.slow_callback_duration` attribute is the minimum - duration in seconds of "slow" callbacks. +* Callbacks taking longer than 100ms are logged. The + :attr:`loop.slow_callback_duration` attribute can be used to set the + minimum execution duration in seconds that is considered "slow". .. _asyncio-multithreading: @@ -134,7 +132,7 @@ Logging asyncio uses the :mod:`logging` module and all logging is performed via the ``"asyncio"`` logger. -The default log level is :py:data:`logging.INFO`, which can easily be +The default log level is :py:data:`logging.INFO`, which can be easily adjusted:: logging.getLogger("asyncio").setLevel(logging.WARNING) @@ -142,12 +140,13 @@ adjusted:: .. _asyncio-coroutine-not-scheduled: -Detect never awaited coroutines +Detect never-awaited coroutines =============================== -When a coroutine is called (e.g. ``coro()`` instead of ``await coro()``) -the call is not wrapped with :meth:`asyncio.create_task`, the execution -of the coroutine object will never be scheduled. For example:: +When a coroutine function is called, but not awaited +(e.g. ``coro()`` instead of ``await coro()``) +or the coroutine is not scheduled with :meth:`asyncio.create_task`, asyncio +will emit a :exc:`RuntimeWarning`:: import asyncio @@ -184,8 +183,8 @@ The usual fix is to either await the coroutine or call the await test() -Detect never consumed exceptions -================================ +Detect never-retrieved exceptions +================================= If a :meth:`Future.set_exception` is called but the Future object is never awaited on, the exception would never be propagated to the diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 909d3ea336..0320d798c1 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -8,20 +8,17 @@ Event Loop .. rubric:: Preface -The event loop is a central component of every asyncio application. +The event loop is the core of every asyncio application. Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. -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. +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. -Alternatively, developers of low-level code, such as libraries and -framework, may need access to the event loop. - -.. rubric:: Accessing Event Loop +.. rubric:: Obtaining the Event Loop The following low-level functions can be used to get, set, or create an event loop: @@ -68,16 +65,16 @@ and :func:`new_event_loop` functions can be altered by This documentation page contains the following sections: * The `Event Loop Methods`_ section is the reference documentation of - event loop APIs; + the event loop APIs; * The `Callback Handles`_ section documents the :class:`Handle` and - :class:`TimerHandle`, instances which are returned from functions, such - as :meth:`loop.call_soon` and :meth:`loop.call_later`; + :class:`TimerHandle` instances which are returned from scheduling + methods such as :meth:`loop.call_soon` and :meth:`loop.call_later`; -* The `Server Objects`_ sections document types returned from +* The `Server Objects`_ section documents types returned from event loop methods like :meth:`loop.create_server`; -* The `Event Loops Implementations`_ section documents the +* The `Event Loop Implementations`_ section documents the :class:`SelectorEventLoop` and :class:`ProactorEventLoop` classes; * The `Examples`_ section showcases how to work with some event @@ -101,11 +98,11 @@ Running and stopping the loop .. method:: loop.run_until_complete(future) - Run until the *future* (an instance of :class:`Future`) is + Run until the *future* (an instance of :class:`Future`) has completed. If the argument is a :ref:`coroutine object ` it - is implicitly wrapped into an :class:`asyncio.Task`. + is implicitly scheduled to run as a :class:`asyncio.Task`. Return the Future's result or raise its exception. @@ -120,7 +117,7 @@ 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 this + Note that new 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. @@ -167,8 +164,6 @@ Running and stopping the loop .. versionadded:: 3.6 -.. _asyncio-pass-keywords: - Scheduling callbacks ^^^^^^^^^^^^^^^^^^^^ @@ -201,18 +196,19 @@ Scheduling callbacks The *context* keyword-only parameter was added. See :pep:`567` for more details. +.. _asyncio-pass-keywords: + .. note:: Most :mod:`asyncio` scheduling functions don't allow passing - keyword arguments. To do that, use :func:`functools.partial`, - e.g.:: + keyword arguments. To do that, use :func:`functools.partial`:: # will schedule "print("Hello", flush=True)" loop.call_soon( functools.partial(print, "Hello", flush=True)) Using partial objects is usually more convenient than using lambdas, - as asyncio can better render partial objects in debug and error + as asyncio can render partial objects better in debug and error messages. @@ -235,8 +231,8 @@ 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 one will - be called first. + scheduled for exactly the same time, the order in which they + are called is undefined. The optional positional *args* will be passed to the callback when it is called. If you want the callback to be called with keyword @@ -250,6 +246,11 @@ clocks to track time. The *context* keyword-only parameter was added. See :pep:`567` for more details. + .. versionchanged:: 3.8 + In Python 3.7 and earlier with the default event loop implementation, + the *delay* could not exceed one day. + This has been fixed in Python 3.8. + .. method:: loop.call_at(when, callback, *args, context=None) Schedule *callback* to be called at the given absolute timestamp @@ -265,6 +266,11 @@ clocks to track time. The *context* keyword-only parameter was added. See :pep:`567` for more details. + .. versionchanged:: 3.8 + In Python 3.7 and earlier with the default event loop implementation, + the difference between *when* and the current time could not exceed + one day. This has been fixed in Python 3.8. + .. method:: loop.time() Return the current time, as a :class:`float` value, according to @@ -314,11 +320,10 @@ Creating Futures and Tasks :meth:`loop.create_task`. If *factory* is ``None`` the default task factory will be set. - - If *factory* is a *callable*, it should have a signature matching - ``(loop, coro)``, where *loop* will be a reference to the active - event loop, *coro* will be a coroutine object. The callable - must return an :class:`asyncio.Future` compatible object. + Otherwise, *factory* must be a *callable* with the signature matching + ``(loop, coro)``, where *loop* is a reference to the active + event loop, and *coro* is a coroutine object. The callable + must return a :class:`asyncio.Future`-compatible object. .. method:: loop.get_task_factory() @@ -365,28 +370,23 @@ Opening network connections The created transport is an implementation-dependent bidirectional stream. - .. note:: - *protocol_factory* can be any kind of callable, not necessarily - a class. For example, if you want to use a pre-created - protocol instance, you can pass ``lambda: my_protocol``. - Other arguments: - * *ssl*: if given and not false, an SSL/TLS transport is created + * *ssl*: if given and not false, a SSL/TLS transport is created (by default a plain TCP transport is created). If *ssl* is a :class:`ssl.SSLContext` object, this context is used to create - the transport; if *ssl* is :const:`True`, a context with some - unspecified default settings is used. + the transport; if *ssl* is :const:`True`, a default context returned + from :func:`ssl.create_default_context` is used. .. seealso:: :ref:`SSL/TLS security considerations ` - * *server_hostname*, is only for use together with *ssl*, - and sets or overrides the hostname that the target server's certificate - will be matched against. By default the value of the *host* argument + * *server_hostname* sets or overrides the hostname that the target + server's certificate will be matched against. Should only be passed + if *ssl* is not ``None``. By default the value of the *host* argument is used. If *host* is empty, there is no default and you must pass a value for *server_hostname*. If *server_hostname* is an empty string, hostname matching is disabled (which is a serious security - risk, allowing for man-in-the-middle-attacks). + risk, allowing for potential man-in-the-middle attacks). * *family*, *proto*, *flags* are the optional address family, protocol and flags to be passed through to getaddrinfo() for *host* resolution. @@ -402,8 +402,8 @@ Opening network connections to bind the socket to locally. The *local_host* and *local_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. + * *ssl_handshake_timeout* is (for a TLS connection) the time in seconds + to wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). .. versionadded:: 3.7 @@ -417,7 +417,7 @@ Opening network connections .. versionchanged:: 3.5 - Added support for SSL/TLS for :class:`ProactorEventLoop`. + Added support for SSL/TLS in :class:`ProactorEventLoop`. .. seealso:: @@ -462,12 +462,12 @@ Opening network connections * *reuse_address* tells the kernel to reuse a local socket in ``TIME_WAIT`` state, without waiting for its natural timeout to expire. If not specified will automatically be set to ``True`` on - UNIX. + Unix. * *reuse_port* tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows - and some UNIX's. If the :py:data:`~socket.SO_REUSEPORT` constant is not + and some Unixes. If the :py:data:`~socket.SO_REUSEPORT` constant is not defined then this capability is unsupported. * *allow_broadcast* tells the kernel to allow this endpoint to send @@ -478,7 +478,7 @@ Opening network connections transport. If specified, *local_addr* and *remote_addr* should be omitted (must be :const:`None`). - On Windows with :class:`ProactorEventLoop`, this method is not supported. + On Windows, with :class:`ProactorEventLoop`, this method is not supported. See :ref:`UDP echo client protocol ` and :ref:`UDP echo server protocol ` examples. @@ -491,22 +491,22 @@ Opening network connections path=None, \*, ssl=None, sock=None, \ server_hostname=None, ssl_handshake_timeout=None) - Create UNIX connection. + Create a Unix connection. The socket family will be :py:data:`~socket.AF_UNIX`; socket type will be :py:data:`~socket.SOCK_STREAM`. A tuple of ``(transport, protocol)`` is returned on success. - *path* is the name of a UNIX domain socket and is required, - unless a *sock* parameter is specified. Abstract UNIX sockets, + *path* is the name of a Unix domain socket and is required, + unless a *sock* parameter is specified. Abstract Unix sockets, :class:`str`, :class:`bytes`, and :class:`~pathlib.Path` paths are supported. See the documentation of the :meth:`loop.create_connection` method for information about arguments to this method. - Availability: UNIX. + Availability: Unix. .. versionadded:: 3.7 @@ -529,7 +529,7 @@ Creating network servers ssl_handshake_timeout=None, start_serving=True) Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) listening - on the *host* and *port* address. + on *port* of the *host* address. Returns a :class:`Server` object. @@ -538,13 +538,18 @@ Creating network servers * *protocol_factory* must be a callable returning a :ref:`protocol ` implementation. - * 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). + * The *host* parameter can be set to several types which determine where + the server would be listening: + + - If *host* is a string, the TCP server is bound to a single network + interface specified by *host*. + + - If *host* is a sequence of strings, the TCP server is bound to all + network interfaces specified by 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. @@ -554,27 +559,26 @@ Creating network servers * *flags* is a bitmask for :meth:`getaddrinfo`. * *sock* can optionally be specified in order to use a preexisting - socket object. If specified, *host* and *port* should be omitted (must be - :const:`None`). + socket object. If specified, *host* and *port* must not be specified. * *backlog* is the maximum number of queued connections passed to :meth:`~socket.socket.listen` (defaults to 100). - * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the - accepted connections. + * *ssl* can be set to an :class:`~ssl.SSLContext` instance to enable + TLS over the accepted connections. * *reuse_address* tells the kernel to reuse a local socket in ``TIME_WAIT`` state, without waiting for its natural timeout to expire. If not specified will automatically be set to ``True`` on - UNIX. + Unix. * *reuse_port* tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows. - * *ssl_handshake_timeout* is (for an SSL server) the time in seconds to wait - for the SSL handshake to complete before aborting the connection. + * *ssl_handshake_timeout* is (for a TLS server) the time in seconds to wait + for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). * *start_serving* set to ``True`` (the default) causes the created server @@ -594,8 +598,7 @@ Creating network servers .. versionchanged:: 3.5 - Added support for SSL/TLS on Windows with - :class:`ProactorEventLoop`. + Added support for SSL/TLS in :class:`ProactorEventLoop`. .. versionchanged:: 3.5.1 @@ -615,15 +618,15 @@ Creating network servers Similar to :meth:`loop.create_server` but works with the :py:data:`~socket.AF_UNIX` socket family. - *path* is the name of a UNIX domain socket, and is required, - unless a *sock* argument is provided. Abstract UNIX sockets, + *path* is the name of a Unix domain socket, and is required, + unless a *sock* argument is provided. Abstract Unix sockets, :class:`str`, :class:`bytes`, and :class:`~pathlib.Path` paths are supported. See the documentation of the :meth:`loop.create_server` method for information about arguments to this method. - Availability: UNIX. + Availability: Unix. .. versionadded:: 3.7 @@ -680,17 +683,17 @@ Transferring files *offset* tells from where to start reading the file. If specified, *count* is the total number of bytes to transmit as opposed to - sending the file until EOF is reached. File position is updated on - return or also in case of error in which case :meth:`file.tell() - ` can be used to figure out the number of bytes - which were sent. + sending the file until EOF is reached. File position is always updated, + even when this method raises an error, and + :meth:`file.tell() ` can be used to obtain the actual + number of bytes sent. *fallback* set to ``True`` makes asyncio to manually read and send the file when the platform does not support the sendfile system call (e.g. Windows or SSL socket on Unix). Raise :exc:`SendfileNotAvailableError` if the system does not support - *sendfile* syscall and *fallback* is ``False``. + the *sendfile* syscall and *fallback* is ``False``. .. versionadded:: 3.7 @@ -722,8 +725,8 @@ TLS Upgrade * *server_hostname*: sets or overrides the host name that the target server's certificate will be matched against. - * *ssl_handshake_timeout* is (for an SSL connection) the time in seconds to - wait for the SSL handshake to complete before aborting the connection. + * *ssl_handshake_timeout* is (for a TLS connection) the time in seconds to + wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). .. versionadded:: 3.7 @@ -734,24 +737,26 @@ Watching file descriptors .. method:: loop.add_reader(fd, callback, \*args) - Start watching the file descriptor *fd* for read availability and - call the *callback* with specified arguments. + Start monitoring the *fd* file descriptor for read availability and + invoke *callback* with the specified arguments once *fd* is available for + reading. .. method:: loop.remove_reader(fd) - Stop watching the file descriptor *fd* for read availability. + Stop monitoring the *fd* file descriptor for read availability. .. method:: loop.add_writer(fd, callback, \*args) - Start watching the file descriptor *fd* for write availability and then - call the *callback* with specified arguments. + Start monitoring the *fd* file descriptor for write availability and + invoke *callback* with the specified arguments once *fd* is available for + writing. Use :func:`functools.partial` :ref:`to pass keywords ` to *func*. .. method:: loop.remove_writer(fd) - Stop watching the file descriptor *fd* for write availability. + Stop monitoring the *fd* file descriptor for write availability. See also :ref:`Platform Support ` section for some limitations of these methods. @@ -769,13 +774,12 @@ convenient. .. coroutinemethod:: loop.sock_recv(sock, nbytes) - Receive data. Asynchronous version of + Receive up to *nbytes* from *sock*. Asynchronous version of :meth:`socket.recv() `. - The received data is returned as a bytes object. The maximum amount - of data to be received is specified by the *nbytes* argument. + Return the received data as a bytes object. - The socket *sock* must be non-blocking. + *sock* must be a non-blocking socket. .. versionchanged:: 3.7 Even though this method was always documented as a coroutine @@ -784,27 +788,27 @@ convenient. .. coroutinemethod:: loop.sock_recv_into(sock, buf) - Receive data into a buffer. Modeled after the blocking + Receive data from *sock* into the *buf* buffer. Modeled after the blocking :meth:`socket.recv_into() ` method. Return the number of bytes written to the buffer. - The socket *sock* must be non-blocking. + *sock* must be a non-blocking socket. .. versionadded:: 3.7 .. coroutinemethod:: loop.sock_sendall(sock, data) - Send data to the socket. Asynchronous version of + Send *data* to the *sock* socket. Asynchronous version of :meth:`socket.sendall() `. - 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 + This method continues to send 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. + *sock* must be a non-blocking socket. .. versionchanged:: 3.7 Even though the method was always documented as a coroutine @@ -813,11 +817,11 @@ convenient. .. coroutinemethod:: loop.sock_connect(sock, address) - Connect to a remote socket at *address*. + Connect *sock* to a remote socket at *address*. Asynchronous version of :meth:`socket.connect() `. - The socket *sock* must be non-blocking. + *sock* must be a non-blocking socket. .. versionchanged:: 3.5.2 ``address`` no longer needs to be resolved. ``sock_connect`` @@ -843,7 +847,7 @@ convenient. and *address* is the address bound to the socket on the other end of the connection. - The socket *sock* must be non-blocking. + *sock* must be a non-blocking socket. .. versionchanged:: 3.7 Even though the method was always documented as a coroutine @@ -858,21 +862,21 @@ convenient. \*, fallback=True) Send a file using high-performance :mod:`os.sendfile` if possible. - Return the total number of bytes which were sent. + Return the total number of bytes sent. Asynchronous version of :meth:`socket.sendfile() `. - *sock* must be non-blocking :class:`~socket.socket` of - :const:`socket.SOCK_STREAM` type. + *sock* must be a non-blocking :const:`socket.SOCK_STREAM` + :class:`~socket.socket`. - *file* must be a regular file object opened in binary mode. + *file* must be a regular file object open in binary mode. *offset* tells from where to start reading the file. If specified, *count* is the total number of bytes to transmit as opposed to - sending the file until EOF is reached. File position is updated on - return or also in case of error in which case :meth:`file.tell() - ` can be used to figure out the number of bytes - which were sent. + sending the file until EOF is reached. File position is always updated, + even when this method raises an error, and + :meth:`file.tell() ` can be used to obtain the actual + number of bytes sent. *fallback*, when set to ``True``, makes asyncio manually read and send the file when the platform does not support the sendfile syscall @@ -881,7 +885,7 @@ convenient. Raise :exc:`SendfileNotAvailableError` if the system does not support *sendfile* syscall and *fallback* is ``False``. - The socket *sock* must be non-blocking. + *sock* must be a non-blocking socket. .. versionadded:: 3.7 @@ -910,7 +914,7 @@ Working with pipes .. coroutinemethod:: loop.connect_read_pipe(protocol_factory, pipe) - Register a read-pipe in the event loop. + Register the read end of *pipe* in the event loop. *protocol_factory* must be a callable returning an :ref:`asyncio protocol ` implementation. @@ -926,7 +930,7 @@ Working with pipes .. coroutinemethod:: loop.connect_write_pipe(protocol_factory, pipe) - Register a write-pipe in the event loop. + Register the write end of *pipe* in the event loop. *protocol_factory* must be a callable returning an :ref:`asyncio protocol ` implementation. @@ -951,12 +955,12 @@ Working with pipes :meth:`loop.subprocess_shell` methods. -UNIX signals +Unix signals ^^^^^^^^^^^^ .. method:: loop.add_signal_handler(signum, callback, \*args) - Add a handler for a signal. + Set *callback* as the handler for the *signum* signal. Raise :exc:`ValueError` if the signal number is invalid or uncatchable. Raise :exc:`RuntimeError` if there is a problem setting up the handler. @@ -966,11 +970,12 @@ UNIX signals .. method:: loop.remove_signal_handler(sig) - Remove a handler for a signal. + Remove the handler for the *sig* signal. - Return ``True`` if a signal handler was removed, ``False`` if not. + Return ``True`` if the signal handler was removed, or ``False`` if + no handler was set for the given signal. -Availability: UNIX. +Availability: Unix. .. seealso:: @@ -982,7 +987,7 @@ Executing code in thread or process pools .. coroutinemethod:: loop.run_in_executor(executor, func, \*args) - Arrange for a *func* to be called in the specified executor. + Arrange for *func* to be called in the specified executor. The *executor* argument should be an :class:`concurrent.futures.Executor` instance. The default executor is used if *executor* is ``None``. @@ -1024,18 +1029,17 @@ Allows customizing how exceptions are handled in the event loop. Set *handler* as the new event loop exception handler. If *handler* is ``None``, the default exception handler will - be set. - - If *handler* is a callable object, it should have a - matching signature to ``(loop, context)``, where ``loop`` - will be a reference to the active event loop, ``context`` - will be a ``dict`` object (see :meth:`call_exception_handler` - documentation for details about context). + be set. Otherwise, *handler* must be a callable with the signature + matching ``(loop, context)``, where ``loop`` + is a reference to the active event loop, and ``context`` + is a ``dict`` object containing the details of the exception + (see :meth:`call_exception_handler` documentation for details + about context). .. method:: loop.get_exception_handler() - Return the exception handler, or ``None`` if the default one - is in use. + Return the current exception handler, or ``None`` if no custom + exception handler was set. .. versionadded:: 3.5.2 @@ -1055,7 +1059,7 @@ Allows customizing how exceptions are handled in the event loop. Call the current event loop exception handler. *context* is a ``dict`` object containing the following keys - (new keys may be introduced later): + (new keys may be introduced in future Python versions): * 'message': Error message; * 'exception' (optional): Exception object; @@ -1068,8 +1072,8 @@ Allows customizing how exceptions are handled in the event loop. .. note:: This method should not be overloaded in subclassed - event loops. For any custom exception handling, use - :meth:`set_exception_handler()` method. + event loops. For custom exception handling, use + the :meth:`set_exception_handler()` method. Enabling debug mode ^^^^^^^^^^^^^^^^^^^ @@ -1099,17 +1103,16 @@ Enabling debug mode Running Subprocesses ^^^^^^^^^^^^^^^^^^^^ -Methods described in this subsections are low-level. In an -async/await code consider using high-level convenient +Methods described in this subsections are low-level. In regular +async/await code consider using the high-level :func:`asyncio.create_subprocess_shell` and -:func:`asyncio.create_subprocess_exec` functions instead. +:func:`asyncio.create_subprocess_exec` convenience functions instead. .. note:: - The default event loop that asyncio is pre-configured - to use on **Windows** does not support subprocesses. - See :ref:`Subprocess Support on Windows ` - for details. + The default asyncio event loop on **Windows** does not support + subprocesses. See :ref:`Subprocess Support on Windows + ` for details. .. coroutinemethod:: loop.subprocess_exec(protocol_factory, \*args, \ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \ @@ -1124,7 +1127,7 @@ async/await code consider using high-level convenient * or :class:`bytes`, encoded to the :ref:`filesystem encoding `. - The first string specifies the program to execute, + The first string specifies the program executable, and the remaining strings specify the arguments. Together, string arguments form the ``argv`` of the program. @@ -1134,7 +1137,7 @@ async/await code consider using high-level convenient a single argument which is list of strings, *subprocess_exec* takes multiple string arguments. - The *protocol_factory* must instantiate a subclass of the + The *protocol_factory* must be a callable returning a subclass of the :class:`asyncio.SubprocessProtocol` class. Other parameters: @@ -1185,7 +1188,7 @@ async/await code consider using high-level convenient This is similar to the standard library :class:`subprocess.Popen` class called with ``shell=True``. - The *protocol_factory* must instantiate a subclass of the + The *protocol_factory* must be a callable returning a subclass of the :class:`SubprocessProtocol` class. See :meth:`~loop.subprocess_exec` for more details about @@ -1197,10 +1200,10 @@ async/await code consider using high-level convenient .. note:: It is the application's responsibility to ensure that all whitespace - and metacharacters are quoted appropriately to avoid `shell injection + and special characters are quoted appropriately to avoid `shell injection `_ vulnerabilities. The :func:`shlex.quote` function can be used to - properly escape whitespace and shell metacharacters in strings that + properly escape whitespace and special characters in strings that are going to be used to construct shell commands. @@ -1214,12 +1217,12 @@ Callback Handles .. method:: cancel() - Cancel the call. If the callback is already canceled or executed, - this method has no effect. + Cancel the callback. If the callback has already been canceled + or executed, this method has no effect. .. method:: cancelled() - Return ``True`` if the call was cancelled. + Return ``True`` if the callback was cancelled. .. versionadded:: 3.7 @@ -1228,7 +1231,7 @@ Callback Handles A callback wrapper object returned by :meth:`loop.call_later`, and :meth:`loop.call_at`. - The class is inherited from :class:`Handle`. + This class is a subclass of :class:`Handle`. .. method:: when() @@ -1280,7 +1283,7 @@ Do not instantiate the class directly. .. method:: get_loop() - Gives the event loop associated with the server object. + Return the event loop associated with the server object. .. versionadded:: 3.7 @@ -1291,12 +1294,12 @@ Do not instantiate the class directly. This method is idempotent, so it can be called when the server is already being serving. - The new *start_serving* keyword-only parameter to + The *start_serving* keyword-only parameter to :meth:`loop.create_server` and - :meth:`asyncio.start_server` allows to create a Server object - that is not accepting connections right away. In which case - this method, or :meth:`Server.serve_forever` can be used - to make the Server object to start accepting connections. + :meth:`asyncio.start_server` allows creating a Server object + that is not accepting connections initially. In this case + ``Server.start_serving()``, or :meth:`Server.serve_forever` can be used + to make the Server start accepting connections. .. versionadded:: 3.7 @@ -1338,19 +1341,19 @@ Do not instantiate the class directly. .. attribute:: sockets - List of :class:`socket.socket` objects the server is listening to, + List of :class:`socket.socket` objects the server is listening on, or ``None`` if the server is closed. .. versionchanged:: 3.7 - Prior to Python 3.7 ``Server.sockets`` used to return the - internal list of server's sockets directly. In 3.7 a copy + Prior to Python 3.7 ``Server.sockets`` used to return an + internal list of server sockets directly. In 3.7 a copy of that list is returned. .. _asyncio-event-loops: -Event Loops Implementations -=========================== +Event Loop Implementations +========================== asyncio ships with two different event loop implementations: :class:`SelectorEventLoop` and :class:`ProactorEventLoop`. @@ -1364,8 +1367,8 @@ on all platforms. An event loop based on the :mod:`selectors` module. Uses the most efficient *selector* available for the given - platform. It is also possible to manually configure what - exact selector implementation should be used:: + platform. It is also possible to manually configure the + exact selector implementation to be used:: import asyncio import selectors @@ -1375,7 +1378,7 @@ on all platforms. asyncio.set_event_loop(loop) - Availability: UNIX, Windows. + Availability: Unix, Windows. .. class:: ProactorEventLoop @@ -1412,9 +1415,9 @@ Examples ======== Note that all examples in this section **purposefully** show how -to use low-level event loop APIs such as :meth:`loop.run_forever` +to use the low-level event loop APIs, such as :meth:`loop.run_forever` and :meth:`loop.call_soon`. Modern asyncio applications rarely -need to be written this way; consider using high-level functions +need to be written this way; consider using the high-level functions like :func:`asyncio.run`. @@ -1456,9 +1459,9 @@ event loop:: Display the current date with call_later() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -An example of callback displaying the current date every second. The +An example of a callback displaying the current date every second. The callback uses the :meth:`loop.call_later` method to reschedule itself -during 5 seconds, and then stops the event loop:: +after 5 seconds, and then stops the event loop:: import asyncio import datetime @@ -1545,7 +1548,7 @@ Wait until a file descriptor received some data using the Set signal handlers for SIGINT and SIGTERM ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -(This ``signals`` 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:: diff --git a/Doc/library/asyncio-exceptions.rst b/Doc/library/asyncio-exceptions.rst index 31bc1edf01..dbd5df7208 100644 --- a/Doc/library/asyncio-exceptions.rst +++ b/Doc/library/asyncio-exceptions.rst @@ -23,12 +23,12 @@ Exceptions This exception can be caught to perform custom operations when asyncio Tasks are cancelled. In almost all situations the - exception must always be re-raised. + exception must be re-raised. .. important:: This exception is a subclass of :exc:`Exception`, so it can be - accidentally suppressed by ``try..except`` block:: + accidentally suppressed by an overly broad ``try..except`` block:: try: await operation @@ -65,27 +65,27 @@ Exceptions .. exception:: IncompleteReadError - Incomplete read error. + The requested read operation did not complete fully. - Raised by :ref:`asyncio streams ` APIs. + Raised by the :ref:`asyncio stream APIs`. This exception is a subclass of :exc:`EOFError`. .. attribute:: expected - Total number (:class:`int`) of expected bytes. + The total number (:class:`int`) of expected bytes. .. attribute:: partial - Read :class:`bytes` string before the end of stream was reached. + A string of :class:`bytes` read before the end of stream was reached. .. exception:: LimitOverrunError - Reached the buffer limit while looking for a separator. + Reached the buffer size limit while looking for a separator. - Raised by :ref:`asyncio streams ` APIs. + Raised by the :ref:`asyncio stream APIs `. .. attribute:: consumed - Total number of to be consumed bytes. + The total number of to be consumed bytes. diff --git a/Doc/library/asyncio-platforms.rst b/Doc/library/asyncio-platforms.rst index 2f0f534952..f8ecb58d3a 100644 --- a/Doc/library/asyncio-platforms.rst +++ b/Doc/library/asyncio-platforms.rst @@ -4,11 +4,11 @@ .. _asyncio-platform-support: -================= -Platforms Support -================= +================ +Platform Support +================ -The :mod:`asyncio` module has been designed to be portable, +The :mod:`asyncio` module is designed to be portable, but some platforms have subtle differences and limitations due to the platforms' underlying architecture and capabilities. @@ -17,7 +17,7 @@ All Platforms ============= * :meth:`loop.add_reader` and :meth:`loop.add_writer` - cannot be used to monitor file IO. + cannot be used to monitor file I/O. Windows @@ -27,7 +27,7 @@ All event loops on Windows do not support the following methods: * :meth:`loop.create_unix_connection` and :meth:`loop.create_unix_server` are not supported. - The :data:`socket.AF_UNIX` socket family is specific to UNIX. + The :data:`socket.AF_UNIX` socket family is specific to Unix. * :meth:`loop.add_signal_handler` and :meth:`loop.remove_signal_handler` are not supported. diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst index 61727d40af..42f936da46 100644 --- a/Doc/library/asyncio-policy.rst +++ b/Doc/library/asyncio-policy.rst @@ -7,9 +7,9 @@ Policies ======== -An event loop policy, a global per-process object, controls -management of the event loop. Each event loop has a default -policy, which can be changed and customized using the API. +An event loop policy is a global per-process object that controls +the management of the event loop. Each event loop has a default +policy, which can be changed and customized using the policy API. A policy defines the notion of *context* and manages a separate event loop per context. The default policy @@ -20,11 +20,11 @@ By using a custom event loop policy, the behavior of :func:`new_event_loop` functions can be customized. Policy objects should implement the APIs defined -in the abstract base class :class:`AbstractEventLoopPolicy`. +in the :class:`AbstractEventLoopPolicy` abstract base class. -Access the Policy -================= +Getting and Setting the Policy +============================== The following functions can be used to get and set the policy for the current process: @@ -111,14 +111,14 @@ Process Watchers A process watcher allows customization of how an event loop monitors child processes on Unix. Specifically, the event loop needs to know -when a child process has finished its execution. +when a child process has exited. In asyncio, child processes are created with :func:`create_subprocess_exec` and :meth:`loop.subprocess_exec` functions. -asyncio defines an abstract base class :class:`AbstractChildWatcher` -that child watchers should implement, and has two different +asyncio defines the :class:`AbstractChildWatcher` abstract base class, +which child watchers should implement, and has two different implementations: :class:`SafeChildWatcher` (configured to be used by default) and :class:`FastChildWatcher`. @@ -141,8 +141,7 @@ implementation used by the asyncio event loop: .. note:: Third-party event loops implementations might not support custom child watchers. For such event loops, using - :func:`set_child_watcher` might have no effect or even can - be prohibited. + :func:`set_child_watcher` might be prohibited or have no effect. .. class:: AbstractChildWatcher @@ -155,7 +154,7 @@ implementation used by the asyncio event loop: another callback for the same process replaces the previous handler. - *callback* callable must be thread-safe. + The *callback* callable must be thread-safe. .. method:: remove_child_handler(pid) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index cb16acd58b..bdfdcf7ddb 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -10,8 +10,8 @@ Transports and Protocols .. rubric:: Preface -Transports and Protocols are used by **low-level** event loop -APIs such as :meth:`loop.create_connection`. They require using +Transports and Protocols are used by the **low-level** event loop +APIs such as :meth:`loop.create_connection`. They use callback-based programming style and enable high-performance implementations of network or IPC protocols (e.g. HTTP). @@ -282,7 +282,7 @@ Write-only Transports .. method:: WriteTransport.get_write_buffer_limits() - Get the *high*- and *low*-water limits for write flow control. Return a + Get the *high* and *low* watermarks for write flow control. Return a tuple ``(low, high)`` where *low* and *high* are positive number of bytes. @@ -292,14 +292,14 @@ Write-only Transports .. method:: WriteTransport.set_write_buffer_limits(high=None, low=None) - Set the *high*- and *low*-water limits for write flow control. + Set the *high* and *low* watermarks for write flow control. These two values (measured in number of bytes) control when the protocol's :meth:`protocol.pause_writing() ` and :meth:`protocol.resume_writing() ` - methods are called. If specified, the low-water limit must be less - than or equal to the high-water limit. Neither *high* nor *low* + methods are called. If specified, the low watermark must be less + than or equal to the high watermark. Neither *high* nor *low* can be negative. :meth:`~BaseProtocol.pause_writing` is called when the buffer size @@ -308,9 +308,9 @@ Write-only Transports the buffer size becomes less than or equal to the *low* value. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to an + high watermark is given, the low watermark defaults to an implementation-specific value less than or equal to the - high-water limit. Setting *high* to zero forces *low* to zero as + high watermark. Setting *high* to zero forces *low* to zero as well, and causes :meth:`~BaseProtocol.pause_writing` to be called whenever the buffer becomes non-empty. Setting *low* to zero causes :meth:`~BaseProtocol.resume_writing` to be called only once the @@ -337,11 +337,11 @@ Write-only Transports .. method:: WriteTransport.write_eof() - Close the write end of the transport after flushing buffered data. + Close the write end of the transport after flushing all buffered data. Data may still be received. This method can raise :exc:`NotImplementedError` if the transport - (e.g. SSL) doesn't support half-closes. + (e.g. SSL) doesn't support half-closed connections. Datagram Transports @@ -506,18 +506,18 @@ method for more details. .. method:: BaseProtocol.pause_writing() - Called when the transport's buffer goes over the high-water mark. + Called when the transport's buffer goes over the high watermark. .. method:: BaseProtocol.resume_writing() - Called when the transport's buffer drains below the low-water mark. + Called when the transport's buffer drains below the low watermark. -If the buffer size equals the high-water mark, +If the buffer size equals the high watermark, :meth:`~BaseProtocol.pause_writing` is not called: the buffer size must go strictly over. Conversely, :meth:`~BaseProtocol.resume_writing` is called when the -buffer size is equal or lower than the low-water mark. These end +buffer size is equal or lower than the low watermark. These end conditions are important to ensure that things go as expected when either mark is zero. @@ -541,13 +541,12 @@ accept factories that return streaming protocols. and instead make your parsing generic and flexible. However, data is always received in the correct order. - The method can be called an arbitrary number of times during - a connection. + The method can be called an arbitrary number of times while + a connection is open. However, :meth:`protocol.eof_received() ` - is called at most once and, if called, - :meth:`protocol.data_received() ` - won't be called after it. + is called at most once. Once `eof_received()` is called, + ``data_received()`` is not called anymore. .. method:: Protocol.eof_received() @@ -562,9 +561,9 @@ accept factories that return streaming protocols. Since the default implementation returns ``None``, it implicitly closes the connection. - Some transports such as SSL don't support half-closed connections, - in which case returning true from this method will result in closing - the connection. + Some transports, including SSL, don't support half-closed connections, + in which case returning true from this method will result in the connection + being closed. State machine: @@ -588,12 +587,12 @@ Buffered Streaming Protocols Buffered Protocols can be used with any event loop method that supports `Streaming Protocols`_. -The idea of ``BufferedProtocol`` is that it allows manual allocation +``BufferedProtocol`` implementations allow explicit manual allocation and control of the receive buffer. Event loops can then use the buffer provided by the protocol to avoid unnecessary data copies. This can result in noticeable performance improvement for protocols that -receive big amounts of data. Sophisticated protocols implementations -can allocate the buffer only once at creation time. +receive big amounts of data. Sophisticated protocol implementations +can significantly reduce the number of buffer allocations. The following callbacks are called on :class:`BufferedProtocol` instances: @@ -602,12 +601,12 @@ instances: Called to allocate a new receive buffer. - *sizehint* is a recommended minimal size for the returned - buffer. It is acceptable to return smaller or bigger buffers + *sizehint* is the recommended minimum size for the returned + buffer. It is acceptable to return smaller or larger buffers than what *sizehint* suggests. When set to -1, the buffer size - can be arbitrary. It is an error to return a zero-sized buffer. + can be arbitrary. It is an error to return a buffer with a zero size. - Must return an object that implements the + ``get_buffer()`` must return an object implementing the :ref:`buffer protocol `. .. method:: BufferedProtocol.buffer_updated(nbytes) @@ -658,14 +657,14 @@ factories passed to the :meth:`loop.create_datagram_endpoint` method. :class:`OSError`. *exc* is the :class:`OSError` instance. This method is called in rare conditions, when the transport (e.g. UDP) - detects that a datagram couldn't be delivered to its recipient. + detects that a datagram could not be delivered to its recipient. In many conditions though, undeliverable datagrams will be silently dropped. .. note:: On BSD systems (macOS, FreeBSD, etc.) flow control is not supported - for datagram protocols, because it is difficult to detect easily send + for datagram protocols, because there is no reliable way to detect send failures caused by writing too many packets. The socket always appears 'ready' and excess packets are dropped. An diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst index 23d2f3cb1d..bd0e70c0d9 100644 --- a/Doc/library/asyncio-queue.rst +++ b/Doc/library/asyncio-queue.rst @@ -10,7 +10,7 @@ asyncio queues are designed to be similar to classes of the :mod:`queue` module. Although asyncio queues are not thread-safe, they are designed to be used specifically in async/await code. -Note that methods on asyncio queues don't have a *timeout* parameter; +Note that methods of asyncio queues don't have a *timeout* parameter; use :func:`asyncio.wait_for` function to do queue operations with a timeout. @@ -72,7 +72,7 @@ Queue .. coroutinemethod:: put(item) Put an item into the queue. If the queue is full, wait until a - free slot is available before adding item. + free slot is available before adding the item. .. method:: put_nowait(item) @@ -82,7 +82,7 @@ Queue .. method:: qsize() - Number of items in the queue. + Return the number of items in the queue. .. method:: task_done() diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 0489201b4d..60aae16c6d 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -54,7 +54,7 @@ and work with streams: :class:`StreamReader` and :class:`StreamWriter` classes. The *loop* argument is optional and can always be determined - automatically when this method is awaited from a coroutine. + automatically when this function is awaited from a coroutine. *limit* determines the buffer size limit used by the returned :class:`StreamReader` instance. By default the *limit* @@ -84,7 +84,7 @@ and work with streams: *client_connected_cb* can be a plain callable or a :ref:`coroutine function `; if it is a coroutine function, - it will be automatically wrapped into a :class:`Task`. + it will be automatically scheduled as a :class:`Task`. The *loop* argument is optional and can always be determined automatically when this method is awaited from a coroutine. @@ -107,14 +107,14 @@ and work with streams: limit=None, ssl=None, sock=None, \ server_hostname=None, ssl_handshake_timeout=None) - Establish a UNIX socket connection and return a pair of + Establish a Unix socket connection and return a pair of ``(reader, writer)``. - Similar to :func:`open_connection` but operates on UNIX sockets. + Similar to :func:`open_connection` but operates on Unix sockets. See also the documentation of :meth:`loop.create_unix_connection`. - Availability: UNIX. + Availability: Unix. .. versionadded:: 3.7 @@ -130,13 +130,13 @@ and work with streams: backlog=100, ssl=None, ssl_handshake_timeout=None, \ start_serving=True) - Start a UNIX socket server. + Start a Unix socket server. - Similar to :func:`start_server` but works with UNIX sockets. + Similar to :func:`start_server` but works with Unix sockets. See also the documentation of :meth:`loop.create_unix_server`. - Availability: UNIX. + Availability: Unix. .. versionadded:: 3.7 @@ -167,7 +167,7 @@ StreamReader Read up to *n* bytes. If *n* is not provided, or set to ``-1``, read until EOF and return all read bytes. - If an EOF was received and the internal buffer is empty, + If EOF was received and the internal buffer is empty, return an empty ``bytes`` object. .. coroutinemethod:: readline() @@ -175,41 +175,36 @@ StreamReader Read one line, where "line" is a sequence of bytes ending with ``\n``. - If an EOF is received and ``\n`` was not found, the method + If EOF is received and ``\n`` was not found, the method returns partially read data. - If an EOF is received and the internal buffer is empty, + If EOF is received and the internal buffer is empty, return an empty ``bytes`` object. .. coroutinemethod:: readexactly(n) Read exactly *n* bytes. - Raise an :exc:`IncompleteReadError` if an EOF reached before *n* + Raise an :exc:`IncompleteReadError` if EOF is reached before *n* can be read. Use the :attr:`IncompleteReadError.partial` attribute to get the partially read data. .. coroutinemethod:: readuntil(separator=b'\\n') - Read data from the stream until ``separator`` is found. + Read data from the stream until *separator* is found. On success, the data and separator will be removed from the internal buffer (consumed). Returned data will include the separator at the end. - Configured stream limit is used to check result. Limit sets the - maximal length of data that can be returned, not counting the - separator. - - If an EOF occurs and the complete separator is still not found, - an :exc:`IncompleteReadError` exception will be - raised, and the internal buffer will be reset. The - :attr:`IncompleteReadError.partial` attribute may contain the - separator partially. + If the amount of data read exceeds the configured stream limit, a + :exc:`LimitOverrunError` exception is raised, and the data + is left in the internal buffer and can be read again. - If the data cannot be read because of over limit, a - :exc:`LimitOverrunError` exception will be raised, and the data - will be left in the internal buffer, so it can be read again. + If EOF is reached before the complete separator is found, + an :exc:`IncompleteReadError` exception is raised, and the internal + buffer is reset. The :attr:`IncompleteReadError.partial` attribute + may contain a portion of the separator. .. versionadded:: 3.5.2 @@ -235,8 +230,8 @@ StreamWriter Write *data* to the stream. - The method respects control-flow, execution is paused if write - buffer reaches high-water limit. + The method respects flow control, execution is paused if the write + buffer reaches the high watermark. .. versionadded:: 3.8 @@ -244,7 +239,7 @@ StreamWriter Close the stream. - Wait for finishing all closing actions, e.g. SSL shutdown for + Wait until all closing actions are complete, e.g. SSL shutdown for secure sockets. .. versionadded:: 3.8 @@ -272,28 +267,29 @@ StreamWriter Write *data* to the stream. - This method doesn't apply control-flow. The call should be - followed by :meth:`drain`. + This method is not subject to flow control. Calls to ``write()`` should + be followed by :meth:`drain`. The :meth:`awrite` method is a + recommended alternative the applies flow control automatically. .. method:: writelines(data) Write a list (or any iterable) of bytes to the stream. - This method doesn't apply control-flow. The call should be - followed by :meth:`drain`. + This method is not subject to flow control. Calls to ``writelines()`` + should be followed by :meth:`drain`. .. coroutinemethod:: drain() Wait until it is appropriate to resume writing to the stream. - E.g.:: + Example:: writer.write(data) await writer.drain() - This is a flow-control method that interacts with the underlying + This is a flow control method that interacts with the underlying IO write buffer. When the size of the buffer reaches - the high-water limit, *drain()* blocks until the size of the - buffer is drained down to the low-water limit and writing can + the high watermark, *drain()* blocks until the size of the + buffer is drained down to the low watermark and writing can be resumed. When there is nothing to wait for, the :meth:`drain` returns immediately. diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index 57a7a378b8..0bcf66175c 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -12,7 +12,7 @@ create and manage subprocesses. .. _asyncio_example_subprocess_shell: Here's an example of how asyncio can run a shell command and -communicate its result back:: +obtain its result:: import asyncio @@ -41,7 +41,7 @@ will print:: Because all asyncio subprocess functions are asynchronous and asyncio provides many tools to work with such functions, it is easy to execute and monitor multiple subprocesses in parallel. It is indeed trivial -to modify the above example to run a few commands at once:: +to modify the above example to run several commands simultaneously:: async def main(): await asyncio.gather( @@ -75,7 +75,7 @@ Creating Subprocesses stdout=None, stderr=None, loop=None, \ limit=None, \*\*kwds) - Run the shell command *cmd*. + Run the *cmd* shell command. The *limit* argument sets the buffer limit for :class:`StreamReader` wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` @@ -89,23 +89,23 @@ Creating Subprocesses .. important:: It is the application's responsibility to ensure that all whitespace and - metacharacters are quoted appropriately to avoid `shell injection + special characters are quoted appropriately to avoid `shell injection `_ vulnerabilities. The :func:`shlex.quote` function can be used to properly - escape whitespace and shell metacharacters in strings that are going to be - used to construct shell commands. + escape whitespace and special shell characters in strings that are going + to be used to construct shell commands. .. note:: - The default event loop that asyncio is pre-configured - to use on **Windows** does not support subprocesses. Subprocesses are - available for Windows if the :class:`ProactorEventLoop` is used. + The default asyncio event loop implementation on **Windows** does not + support subprocesses. Subprocesses are available for Windows if a + :class:`ProactorEventLoop` is used. See :ref:`Subprocess Support on Windows ` for details. .. seealso:: - asyncio has also *low-level* APIs to work with subprocesses: + asyncio also has the following *low-level* APIs to work with subprocesses: :meth:`loop.subprocess_exec`, :meth:`loop.subprocess_shell`, :meth:`loop.connect_read_pipe`, :meth:`loop.connect_write_pipe`, as well as the :ref:`Subprocess Transports ` @@ -130,22 +130,23 @@ Constants .. data:: asyncio.subprocess.STDOUT - Can be passed to the *stderr* parameter to redirect process' - *stderr* to *stdout*. + Special value that can be used as the *stderr* argument and indicates + that standard error should be redirected into standard output. .. data:: asyncio.subprocess.DEVNULL - Can be passed as the *stdin*, *stdout* or *stderr* parameters - to redirect the corresponding subprocess' IO to :data:`os.devnull`. + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to process creation functions. It indicates that the special file + :data:`os.devnull` will be used for the corresponding subprocess stream. Interacting with Subprocesses ============================= Both :func:`create_subprocess_exec` and :func:`create_subprocess_shell` -functions return instances of the *Process* class. It is a high-level -wrapper that allows to watch for subprocesses completion and -communicate with them. +functions return instances of the *Process* class. *Process* is a high-level +wrapper that allows communicating with subprocesses and watching for +their completion. .. class:: asyncio.subprocess.Process @@ -161,7 +162,7 @@ communicate with them. the :meth:`~subprocess.Popen.poll` method; * the :meth:`~asyncio.subprocess.Process.communicate` and - :meth:`~asyncio.subprocess.Process.wait` methods don't take a + :meth:`~asyncio.subprocess.Process.wait` methods don't have a *timeout* parameter: use the :func:`wait_for` function; * the :meth:`Process.wait() ` method @@ -177,7 +178,7 @@ communicate with them. .. coroutinemethod:: wait() - Wait for child process to terminate. + Wait for the child process to terminate. Set and return the :attr:`returncode` attribute. @@ -229,9 +230,9 @@ communicate with them. .. method:: terminate() - Stop the child. + Stop the child process. - On Posix OSs the method sends :py:data:`signal.SIGTERM` to the + On POSIX systems this method sends :py:data:`signal.SIGTERM` to the child process. On Windows the Win32 API function :c:func:`TerminateProcess` is @@ -241,7 +242,7 @@ communicate with them. Kill the child. - On Posix OSs the function sends :py:data:`SIGKILL` to the child + On POSIX systems this method sends :py:data:`SIGKILL` to the child process. On Windows this method is an alias for :meth:`terminate`. @@ -284,7 +285,7 @@ communicate with them. A ``None`` value indicates that the process has not terminated yet. A negative value ``-N`` indicates that the child was terminated - by signal ``N`` (Unix only). + by signal ``N`` (POSIX only). .. _asyncio-subprocess-threads: @@ -292,17 +293,17 @@ communicate with them. Subprocess and Threads ---------------------- -asyncio built-in event loops support running subprocesses from -different threads, but there are the following limitations: +Standard asyncio event loop supports running subprocesses from +different threads, but there are limitations: * An event loop must run in the main thread. -* The child watcher must be instantiated in the main thread, +* The child watcher must be instantiated in the main thread before executing subprocesses from other threads. Call the :func:`get_child_watcher` function in the main thread to instantiate the child watcher. -Note, that alternative event loop implementations might not share +Note that alternative event loop implementations might not share the above limitations; please refer to their documentation. .. seealso:: @@ -316,7 +317,7 @@ Examples An example using the :class:`~asyncio.subprocess.Process` class to control a subprocess and the :class:`StreamReader` class to read from -the *stdout*. +its standard output. .. _asyncio_example_create_subprocess_exec: diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index f29988554c..18b5629704 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -10,10 +10,10 @@ asyncio synchronization primitives are designed to be similar to those of the :mod:`threading` module with two important caveats: * asyncio primitives are not thread-safe, therefore they should not - be used for OS threads synchronization (use :mod:`threading` for + be used for OS thread synchronization (use :mod:`threading` for that); -* methods of synchronization primitives do not accept the *timeout* +* methods of these synchronization primitives do not accept the *timeout* argument; use the :func:`asyncio.wait_for` function to perform operations with timeouts. @@ -153,12 +153,12 @@ Condition A Condition object. Not thread-safe. An asyncio condition primitive can be used by a task to wait for - some event to happen and then get an exclusive access to a shared + some event to happen and then get exclusive access to a shared resource. In essence, a Condition object combines the functionality - of :class:`Event` and :class:`Lock`. It is possible to have many - Condition objects sharing one Lock, which allows to coordinate + of an :class:`Event` and a :class:`Lock`. It is possible to have + multiple Condition objects share one Lock, which allows coordinating exclusive access to a shared resource between different tasks interested in particular states of that shared resource. @@ -287,7 +287,7 @@ Semaphore Acquire a semaphore. If the internal counter is greater than zero, decrement - it by one and return ``True`` immediately. If it is zero wait + it by one and return ``True`` immediately. If it is zero, wait until a :meth:`release` is called and return ``True``. .. method:: locked() @@ -300,7 +300,7 @@ Semaphore Can wake up a task waiting to acquire the semaphore. Unlike :class:`BoundedSemaphore`, :class:`Semaphore` allows - to make more ``release()`` calls than ``acquire()`` calls. + making more ``release()`` calls than ``acquire()`` calls. BoundedSemaphore diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 3faaf0cdb9..4893a7c752 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -20,7 +20,7 @@ Coroutines Coroutines declared with async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet -of code prints "hello", waits 1 second, and prints "world":: +of code prints "hello", waits 1 second, and then prints "world":: >>> import asyncio @@ -41,10 +41,10 @@ be executed:: To actually run a coroutine asyncio provides three main mechanisms: -* By using the :func:`asyncio.run` function to run the top-level +* The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.) -* By awaiting on a coroutine. The following snippet of code will +* Awaiting on a coroutine. The following snippet of code will print "hello" after waiting for 1 second, and then print "world" after waiting for *another* 2 seconds:: @@ -72,7 +72,7 @@ To actually run a coroutine asyncio provides three main mechanisms: world finished at 17:13:55 -* By using the :func:`asyncio.create_task` function to run coroutines +* The :func:`asyncio.create_task` function to run coroutines concurrently as asyncio :class:`Tasks `. Let's modify the above example and run two "set_after" coroutines @@ -130,8 +130,8 @@ Running an asyncio Program programs, and should ideally only be called once. .. versionadded:: 3.7 - **Important:** this has been added to asyncio in Python 3.7 - on a :term:`provisional basis `. + **Important:** this function has been added to asyncio in + Python 3.7 on a :term:`provisional basis `. Creating Tasks @@ -139,13 +139,13 @@ Creating Tasks .. function:: create_task(coro, \*, name=None) - Wrap a :ref:`coroutine ` *coro* into a task and schedule + Wrap the *coro* :ref:`coroutine ` into a task and schedule its execution. Return the task object. If *name* is not ``None``, it is set as the name of the task using :meth:`Task.set_name`. - The task is executed in :func:`get_running_loop` context, + The task is executed in the loop returned by :func:`get_running_loop`, :exc:`RuntimeError` is raised if there is no running loop in current thread. @@ -168,7 +168,7 @@ Sleeping .. _asyncio_example_sleep: Example of coroutine displaying the current date every second - during 5 seconds:: + for 5 seconds:: import asyncio import datetime @@ -198,7 +198,7 @@ Running Tasks Concurrently order of the original *fs* sequence. All coroutines in the *fs* list are automatically - wrapped in :class:`Tasks `. + scheduled as :class:`Tasks `. If *return_exceptions* is ``True``, exceptions in the Tasks/Futures are treated the same as successful results, and gathered in the @@ -263,14 +263,14 @@ Shielding Tasks From Cancellation Wait for a Future/Task while protecting it from being cancelled. *fut* can be a coroutine, a Task, or a Future-like object. If - *fut* is a coroutine it is automatically wrapped in a + *fut* is a coroutine it is automatically scheduled as a :class:`Task`. The statement:: res = await shield(something()) - is equivalent to the statement:: + is equivalent to:: res = await something() @@ -278,7 +278,7 @@ Shielding Tasks From Cancellation Task running in ``something()`` is not cancelled. From the point of view of ``something()``, the cancellation did not happen. Although its caller is still cancelled, so the "await" expression - still raises :exc:`CancelledError`. + still raises a :exc:`CancelledError`. If ``something()`` is cancelled by other means (i.e. from within itself) that would also cancel ``shield()``. @@ -298,10 +298,10 @@ Timeouts .. coroutinefunction:: wait_for(fut, timeout, \*, loop=None) - Wait for the coroutine, Task, or Future to complete with timeout. + Wait for a coroutine, Task, or Future to complete with timeout. *fut* can be a coroutine, a Task, or a Future-like object. If - *fut* is a coroutine it is automatically wrapped in a + *fut* is a coroutine it is automatically scheduled as a :class:`Task`. *timeout* can either be ``None`` or a float or int number of seconds @@ -352,10 +352,10 @@ Waiting Primitives .. coroutinefunction:: wait(fs, \*, loop=None, timeout=None,\ return_when=ALL_COMPLETED) - Wait for a set of Futures to complete. + Wait for a set of coroutines, Tasks, or Futures to complete. *fs* is a list of coroutines, Futures, and/or Tasks. Coroutines - are automatically wrapped in :class:`Tasks `. + are automatically scheduled as :class:`Tasks `. Returns two sets of Tasks/Futures: ``(done, pending)``. @@ -363,7 +363,7 @@ Waiting Primitives the maximum number of seconds to wait before returning. Note that this function does not raise :exc:`asyncio.TimeoutError`. - Futures or Tasks that aren't done when the timeout occurs are just + Futures or Tasks that aren't done when the timeout occurs are simply returned in the second set. *return_when* indicates when this function should return. It must @@ -397,7 +397,7 @@ Waiting Primitives .. function:: as_completed(fs, \*, loop=None, timeout=None) - Return an iterator which values, when waited for, are + Return an iterator of awaitables which return :class:`Future` instances. Raises :exc:`asyncio.TimeoutError` if the timeout occurs before @@ -500,9 +500,9 @@ Task Object IO operations. Use the high-level :func:`asyncio.create_task` function to create - Tasks, or low-level :meth:`loop.create_task` or - :func:`ensure_future` functions. Manually instantiating Task - objects is discouraged. + Tasks, or the low-level :meth:`loop.create_task` or + :func:`ensure_future` functions. Manual instantiation of Tasks + is discouraged. To cancel a running Task use the :meth:`cancel` method. Calling it will cause the Task to throw a :exc:`CancelledError` exception into @@ -660,7 +660,7 @@ Task Object If *loop* is ``None``, the :func:`get_event_loop` function is used to get the current loop. - This function is **deprecated** and scheduled for removal in + This method is **deprecated** and will be removed in Python 3.9. Use the :func:`all_tasks` function instead. .. classmethod:: current_task(loop=None) @@ -670,7 +670,7 @@ Task Object If *loop* is ``None``, the :func:`get_event_loop` function is used to get the current loop. - This function is **deprecated** and scheduled for removal in + This method is **deprecated** and will be removed in Python 3.9. Use the :func:`current_task` function instead. @@ -682,10 +682,10 @@ Generator-based Coroutines .. note:: Support for generator-based coroutines is **deprecated** and - scheduled for removal in Python 4.0. + is scheduled for removal in Python 4.0. Generator-based coroutines predate async/await syntax. They are -Python generators that use ``yield from`` expression is to await +Python generators that use ``yield from`` expressions to await on Futures and other coroutines. Generator-based coroutines should be decorated with diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 73b0e63a68..bfc97001bb 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -20,7 +20,7 @@ asyncio.run(main()) asyncio is a library to write **concurrent** code using -**async/await** syntax. +the **async/await** syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, @@ -42,7 +42,8 @@ asyncio provides a set of **high-level** APIs to: * :ref:`synchronize ` concurrent code; -as well as **low-level** APIs for *library and framework developers* to: +Additionally, there are **low-level** APIs for +*library and framework developers* to: * create and manage :ref:`event loops `, which provide asynchronous APIs for :meth:`networking `, -- 2.40.0