Skip to content

Commit

Permalink
bpo-36889: Document Stream class and add docstrings (GH-14488)
Browse files Browse the repository at this point in the history
* This just copies the docs from `StreamWriter` and `StreamReader`.
* Add docstring for asyncio functions.


https://bugs.python.org/issue36889



Automerge-Triggered-By: @asvetlov
  • Loading branch information
tirkarthi authored and miss-islington committed Sep 13, 2019
1 parent 6a517c6 commit d31b315
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 11 deletions.
36 changes: 30 additions & 6 deletions Doc/library/asyncio-api-index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,47 @@ High-level APIs to work with network IO.
:widths: 50 50
:class: full-width-table

* - ``await`` :func:`connect`
- Establish a TCP connection to send and receive data.

* - ``await`` :func:`open_connection`
- Establish a TCP connection.
- Establish a TCP connection. (Deprecated in favor of :func:`connect`)

* - ``await`` :func:`connect_unix`
- Establish a Unix socket connection to send and receive data.

* - ``await`` :func:`open_unix_connection`
- Establish a Unix socket connection.
- Establish a Unix socket connection. (Deprecated in favor of :func:`connect_unix`)

* - ``await`` :func:`start_server`
* - :class:`StreamServer`
- Start a TCP server.

* - ``await`` :func:`start_unix_server`
* - ``await`` :func:`start_server`
- Start a TCP server. (Deprecated in favor of :class:`StreamServer`)

* - :class:`UnixStreamServer`
- Start a Unix socket server.

* - ``await`` :func:`start_unix_server`
- Start a Unix socket server. (Deprecated in favor of :class:`UnixStreamServer`)

* - :func:`connect_read_pipe`
- Establish a connection to :term:`file-like object <file object>` *pipe*
to receive data.

* - :func:`connect_write_pipe`
- Establish a connection to :term:`file-like object <file object>` *pipe*
to send data.

* - :class:`Stream`
- Stream is a single object combining APIs of :class:`StreamReader` and
:class:`StreamWriter`.

* - :class:`StreamReader`
- High-level async/await object to receive network data.
- High-level async/await object to receive network data. (Deprecated in favor of :class:`Stream`)

* - :class:`StreamWriter`
- High-level async/await object to send network data.
- High-level async/await object to send network data. (Deprecated in favor of :class:`Stream`)


.. rubric:: Examples
Expand Down
179 changes: 174 additions & 5 deletions Doc/library/asyncio-stream.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ and work with streams:
Connect to TCP socket on *host* : *port* address and return a :class:`Stream`
object of mode :attr:`StreamMode.READWRITE`.


*limit* determines the buffer size limit used by the returned :class:`Stream`
instance. By default the *limit* is set to 64 KiB.

Expand Down Expand Up @@ -367,13 +366,184 @@ Stream

Represents a Stream object that provides APIs to read and write data
to the IO stream . It includes the API provided by :class:`StreamReader`
and :class:`StreamWriter`.
and :class:`StreamWriter`. It can also be used as :term:`asynchronous iterator`
where :meth:`readline` is used. It raises :exc:`StopAsyncIteration` when
:meth:`readline` returns empty data.

Do not instantiate *Stream* objects directly; use API like :func:`connect`
and :class:`StreamServer` instead.

.. versionadded:: 3.8

.. attribute:: mode

Returns the mode of the stream which is a :class:`StreamMode` value. It could
be one of the below:

* :attr:`StreamMode.READ` - Connection can receive data.
* :attr:`StreamMode.WRITE` - Connection can send data.
* :attr:`StreamMode.READWRITE` - Connection can send and receive data.

.. coroutinemethod:: abort()

Aborts the connection immediately, without waiting for the send buffer to drain.

.. method:: at_eof()

Return ``True`` if the buffer is empty.

.. method:: can_write_eof()

Return *True* if the underlying transport supports
the :meth:`write_eof` method, *False* otherwise.

.. method:: close()

The method closes the stream and the underlying socket.

It is possible to directly await on the `close()` method::

await stream.close()

The ``await`` pauses the current coroutine until the stream and the underlying
socket are closed (and SSL shutdown is performed for a secure connection).

.. coroutinemethod:: drain()

Wait until it is appropriate to resume writing to the stream.
Example::

stream.write(data)
await stream.drain()

This is a flow control method that interacts with the underlying
IO write buffer. When the size of the buffer reaches
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.

.. deprecated:: 3.8

It is recommended to directly await on the `write()` method instead::

await stream.write(data)

.. method:: get_extra_info(name, default=None)

Access optional transport information; see
:meth:`BaseTransport.get_extra_info` for details.

.. method:: is_closing()

Return ``True`` if the stream is closed or in the process of
being closed.

.. coroutinemethod:: read(n=-1)

Read up to *n* bytes. If *n* is not provided, or set to ``-1``,
read until EOF and return all read bytes.

If EOF was received and the internal buffer is empty,
return an empty ``bytes`` object.

.. coroutinemethod:: readexactly(n)

Read exactly *n* bytes.

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:: readline()

Read one line, where "line" is a sequence of bytes
ending with ``\n``.

If EOF is received and ``\n`` was not found, the method
returns partially read data.

If EOF is received and the internal buffer is empty,
return an empty ``bytes`` object.

.. coroutinemethod:: readuntil(separator=b'\\n')

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.

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

.. coroutinemethod:: sendfile(file, offset=0, count=None, *, fallback=True)

Sends a *file* over the stream using an optimized syscall if available.

For other parameters meaning please see :meth:`AbstractEventloop.sendfile`.

.. coroutinemethod:: start_tls(sslcontext, *, server_hostname=None, \
ssl_handshake_timeout=None)

Upgrades the existing transport-based connection to TLS.

For other parameters meaning please see :meth:`AbstractEventloop.start_tls`.

.. coroutinemethod:: wait_closed()

Wait until the stream is closed.

Should be called after :meth:`close` to wait until the underlying
connection is closed.

.. coroutinemethod:: write(data)

Write *data* to the underlying socket; wait until the data is sent, e.g.::

await stream.write(data)

.. method:: write(data)

The method attempts to write the *data* to the underlying socket immediately.
If that fails, the data is queued in an internal write buffer until it can be
sent. :meth:`drain` can be used to flush the underlying buffer once writing is
available::

stream.write(data)
await stream.drain()

.. deprecated:: 3.8

It is recommended to directly await on the `write()` method instead::

await stream.write(data)

.. method:: writelines(data)

The method writes a list (or any iterable) of bytes to the underlying socket
immediately.
If that fails, the data is queued in an internal write buffer until it can be
sent.

It is possible to directly await on the `writelines()` method::

await stream.writelines(lines)

The ``await`` pauses the current coroutine until the data is written to the
socket.

.. method:: write_eof()

Close the write end of the stream after the buffered write
data is flushed.


StreamMode
==========
Expand Down Expand Up @@ -459,8 +629,7 @@ StreamReader

.. method:: at_eof()

Return ``True`` if the buffer is empty and :meth:`feed_eof`
was called.
Return ``True`` if the buffer is empty.


StreamWriter
Expand Down Expand Up @@ -504,7 +673,7 @@ StreamWriter
If that fails, the data is queued in an internal write buffer until it can be
sent.

Starting with Python 3.8, it is possible to directly await on the `write()`
Starting with Python 3.8, it is possible to directly await on the `writelines()`
method::

await stream.writelines(lines)
Expand Down
21 changes: 21 additions & 0 deletions Lib/asyncio/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ def connect(host=None, port=None, *,
server_hostname=None,
ssl_handshake_timeout=None,
happy_eyeballs_delay=None, interleave=None):
"""Connect to TCP socket on *host* : *port* address to send and receive data.
*limit* determines the buffer size limit used by the returned `Stream`
instance. By default the *limit* is set to 64 KiB.
The rest of the arguments are passed directly to `loop.create_connection()`.
"""
# Design note:
# Don't use decorator approach but explicit non-async
# function to fail fast and explicitly
Expand Down Expand Up @@ -108,6 +115,13 @@ async def _connect(host, port,


def connect_read_pipe(pipe, *, limit=_DEFAULT_LIMIT):
"""Establish a connection to a file-like object *pipe* to receive data.
Takes a file-like object *pipe* to return a Stream object of the mode
StreamMode.READ that has similar API of StreamReader. It can also be used
as an async context manager.
"""

# Design note:
# Don't use decorator approach but explicit non-async
# function to fail fast and explicitly
Expand All @@ -129,6 +143,13 @@ async def _connect_read_pipe(pipe, limit):


def connect_write_pipe(pipe, *, limit=_DEFAULT_LIMIT):
"""Establish a connection to a file-like object *pipe* to send data.
Takes a file-like object *pipe* to return a Stream object of the mode
StreamMode.WRITE that has similar API of StreamWriter. It can also be used
as an async context manager.
"""

# Design note:
# Don't use decorator approach but explicit non-async
# function to fail fast and explicitly
Expand Down

0 comments on commit d31b315

Please sign in to comment.