Commit 1fa2ec49 authored by Elvis Pranskevichus's avatar Elvis Pranskevichus Committed by Yury Selivanov

bpo-33649: A copy-editing pass on asyncio documentation (GH-9376)

parent 3085534c
......@@ -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 <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
<asyncio-coroutine-not-scheduled>`; this mitigates the "forgotten
await" pitfall.
* asyncio checks for :ref:`coroutines that were not awaited
<asyncio-coroutine-not-scheduled>` 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
......
This diff is collapsed.
......@@ -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 <asyncio-streams>` APIs.
Raised by the :ref:`asyncio stream APIs<asyncio-streams>`.
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 <asyncio-streams>` APIs.
Raised by the :ref:`asyncio stream APIs <asyncio-streams>`.
.. attribute:: consumed
Total number of to be consumed bytes.
The total number of to be consumed bytes.
......@@ -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.
......
......@@ -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)
......
......@@ -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() <BaseProtocol.pause_writing>`
and :meth:`protocol.resume_writing() <BaseProtocol.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() <Protocol.eof_received>`
is called at most once and, if called,
:meth:`protocol.data_received() <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 <bufferobjects>`.
.. 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
......
......@@ -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()
......
......@@ -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 <coroutine>`; 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.
......
......@@ -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
<https://en.wikipedia.org/wiki/Shell_injection#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 <asyncio-windows-subprocess>`
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 <asyncio-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() <asyncio.subprocess.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:
......
......@@ -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
......
......@@ -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 <Task>`.
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 <provisional api>`.
**Important:** this function has been added to asyncio in
Python 3.7 on a :term:`provisional basis <provisional api>`.
Creating Tasks
......@@ -139,13 +139,13 @@ Creating Tasks
.. function:: create_task(coro, \*, name=None)
Wrap a :ref:`coroutine <coroutine>` *coro* into a task and schedule
Wrap the *coro* :ref:`coroutine <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 <Task>`.
scheduled as :class:`Tasks <Task>`.
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 <Task>`.
are automatically scheduled as :class:`Tasks <Task>`.
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
......
......@@ -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 <asyncio-sync>` 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 <asyncio-event-loop>`, which
provide asynchronous APIs for :meth:`networking <loop.create_server>`,
......
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