Skip to content

Commit d31b315

Browse files
tirkarthimiss-islington
authored andcommitted
bpo-36889: Document Stream class and add docstrings (GH-14488)
* This just copies the docs from `StreamWriter` and `StreamReader`. * Add docstring for asyncio functions. https://bugs.python.org/issue36889 Automerge-Triggered-By: @asvetlov
1 parent 6a517c6 commit d31b315

File tree

3 files changed

+225
-11
lines changed

3 files changed

+225
-11
lines changed

Doc/library/asyncio-api-index.rst

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,47 @@ High-level APIs to work with network IO.
132132
:widths: 50 50
133133
:class: full-width-table
134134

135+
* - ``await`` :func:`connect`
136+
- Establish a TCP connection to send and receive data.
137+
135138
* - ``await`` :func:`open_connection`
136-
- Establish a TCP connection.
139+
- Establish a TCP connection. (Deprecated in favor of :func:`connect`)
140+
141+
* - ``await`` :func:`connect_unix`
142+
- Establish a Unix socket connection to send and receive data.
137143

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

141-
* - ``await`` :func:`start_server`
147+
* - :class:`StreamServer`
142148
- Start a TCP server.
143149

144-
* - ``await`` :func:`start_unix_server`
150+
* - ``await`` :func:`start_server`
151+
- Start a TCP server. (Deprecated in favor of :class:`StreamServer`)
152+
153+
* - :class:`UnixStreamServer`
145154
- Start a Unix socket server.
146155

156+
* - ``await`` :func:`start_unix_server`
157+
- Start a Unix socket server. (Deprecated in favor of :class:`UnixStreamServer`)
158+
159+
* - :func:`connect_read_pipe`
160+
- Establish a connection to :term:`file-like object <file object>` *pipe*
161+
to receive data.
162+
163+
* - :func:`connect_write_pipe`
164+
- Establish a connection to :term:`file-like object <file object>` *pipe*
165+
to send data.
166+
167+
* - :class:`Stream`
168+
- Stream is a single object combining APIs of :class:`StreamReader` and
169+
:class:`StreamWriter`.
170+
147171
* - :class:`StreamReader`
148-
- High-level async/await object to receive network data.
172+
- High-level async/await object to receive network data. (Deprecated in favor of :class:`Stream`)
149173

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

153177

154178
.. rubric:: Examples

Doc/library/asyncio-stream.rst

Lines changed: 174 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ and work with streams:
4646
Connect to TCP socket on *host* : *port* address and return a :class:`Stream`
4747
object of mode :attr:`StreamMode.READWRITE`.
4848

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

@@ -367,13 +366,184 @@ Stream
367366

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

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

375376
.. versionadded:: 3.8
376377

378+
.. attribute:: mode
379+
380+
Returns the mode of the stream which is a :class:`StreamMode` value. It could
381+
be one of the below:
382+
383+
* :attr:`StreamMode.READ` - Connection can receive data.
384+
* :attr:`StreamMode.WRITE` - Connection can send data.
385+
* :attr:`StreamMode.READWRITE` - Connection can send and receive data.
386+
387+
.. coroutinemethod:: abort()
388+
389+
Aborts the connection immediately, without waiting for the send buffer to drain.
390+
391+
.. method:: at_eof()
392+
393+
Return ``True`` if the buffer is empty.
394+
395+
.. method:: can_write_eof()
396+
397+
Return *True* if the underlying transport supports
398+
the :meth:`write_eof` method, *False* otherwise.
399+
400+
.. method:: close()
401+
402+
The method closes the stream and the underlying socket.
403+
404+
It is possible to directly await on the `close()` method::
405+
406+
await stream.close()
407+
408+
The ``await`` pauses the current coroutine until the stream and the underlying
409+
socket are closed (and SSL shutdown is performed for a secure connection).
410+
411+
.. coroutinemethod:: drain()
412+
413+
Wait until it is appropriate to resume writing to the stream.
414+
Example::
415+
416+
stream.write(data)
417+
await stream.drain()
418+
419+
This is a flow control method that interacts with the underlying
420+
IO write buffer. When the size of the buffer reaches
421+
the high watermark, *drain()* blocks until the size of the
422+
buffer is drained down to the low watermark and writing can
423+
be resumed. When there is nothing to wait for, the :meth:`drain`
424+
returns immediately.
425+
426+
.. deprecated:: 3.8
427+
428+
It is recommended to directly await on the `write()` method instead::
429+
430+
await stream.write(data)
431+
432+
.. method:: get_extra_info(name, default=None)
433+
434+
Access optional transport information; see
435+
:meth:`BaseTransport.get_extra_info` for details.
436+
437+
.. method:: is_closing()
438+
439+
Return ``True`` if the stream is closed or in the process of
440+
being closed.
441+
442+
.. coroutinemethod:: read(n=-1)
443+
444+
Read up to *n* bytes. If *n* is not provided, or set to ``-1``,
445+
read until EOF and return all read bytes.
446+
447+
If EOF was received and the internal buffer is empty,
448+
return an empty ``bytes`` object.
449+
450+
.. coroutinemethod:: readexactly(n)
451+
452+
Read exactly *n* bytes.
453+
454+
Raise an :exc:`IncompleteReadError` if EOF is reached before *n*
455+
can be read. Use the :attr:`IncompleteReadError.partial`
456+
attribute to get the partially read data.
457+
458+
.. coroutinemethod:: readline()
459+
460+
Read one line, where "line" is a sequence of bytes
461+
ending with ``\n``.
462+
463+
If EOF is received and ``\n`` was not found, the method
464+
returns partially read data.
465+
466+
If EOF is received and the internal buffer is empty,
467+
return an empty ``bytes`` object.
468+
469+
.. coroutinemethod:: readuntil(separator=b'\\n')
470+
471+
Read data from the stream until *separator* is found.
472+
473+
On success, the data and separator will be removed from the
474+
internal buffer (consumed). Returned data will include the
475+
separator at the end.
476+
477+
If the amount of data read exceeds the configured stream limit, a
478+
:exc:`LimitOverrunError` exception is raised, and the data
479+
is left in the internal buffer and can be read again.
480+
481+
If EOF is reached before the complete separator is found,
482+
an :exc:`IncompleteReadError` exception is raised, and the internal
483+
buffer is reset. The :attr:`IncompleteReadError.partial` attribute
484+
may contain a portion of the separator.
485+
486+
.. coroutinemethod:: sendfile(file, offset=0, count=None, *, fallback=True)
487+
488+
Sends a *file* over the stream using an optimized syscall if available.
489+
490+
For other parameters meaning please see :meth:`AbstractEventloop.sendfile`.
491+
492+
.. coroutinemethod:: start_tls(sslcontext, *, server_hostname=None, \
493+
ssl_handshake_timeout=None)
494+
495+
Upgrades the existing transport-based connection to TLS.
496+
497+
For other parameters meaning please see :meth:`AbstractEventloop.start_tls`.
498+
499+
.. coroutinemethod:: wait_closed()
500+
501+
Wait until the stream is closed.
502+
503+
Should be called after :meth:`close` to wait until the underlying
504+
connection is closed.
505+
506+
.. coroutinemethod:: write(data)
507+
508+
Write *data* to the underlying socket; wait until the data is sent, e.g.::
509+
510+
await stream.write(data)
511+
512+
.. method:: write(data)
513+
514+
The method attempts to write the *data* to the underlying socket immediately.
515+
If that fails, the data is queued in an internal write buffer until it can be
516+
sent. :meth:`drain` can be used to flush the underlying buffer once writing is
517+
available::
518+
519+
stream.write(data)
520+
await stream.drain()
521+
522+
.. deprecated:: 3.8
523+
524+
It is recommended to directly await on the `write()` method instead::
525+
526+
await stream.write(data)
527+
528+
.. method:: writelines(data)
529+
530+
The method writes a list (or any iterable) of bytes to the underlying socket
531+
immediately.
532+
If that fails, the data is queued in an internal write buffer until it can be
533+
sent.
534+
535+
It is possible to directly await on the `writelines()` method::
536+
537+
await stream.writelines(lines)
538+
539+
The ``await`` pauses the current coroutine until the data is written to the
540+
socket.
541+
542+
.. method:: write_eof()
543+
544+
Close the write end of the stream after the buffered write
545+
data is flushed.
546+
377547

378548
StreamMode
379549
==========
@@ -459,8 +629,7 @@ StreamReader
459629

460630
.. method:: at_eof()
461631

462-
Return ``True`` if the buffer is empty and :meth:`feed_eof`
463-
was called.
632+
Return ``True`` if the buffer is empty.
464633

465634

466635
StreamWriter
@@ -504,7 +673,7 @@ StreamWriter
504673
If that fails, the data is queued in an internal write buffer until it can be
505674
sent.
506675

507-
Starting with Python 3.8, it is possible to directly await on the `write()`
676+
Starting with Python 3.8, it is possible to directly await on the `writelines()`
508677
method::
509678

510679
await stream.writelines(lines)

Lib/asyncio/streams.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ def connect(host=None, port=None, *,
7070
server_hostname=None,
7171
ssl_handshake_timeout=None,
7272
happy_eyeballs_delay=None, interleave=None):
73+
"""Connect to TCP socket on *host* : *port* address to send and receive data.
74+
75+
*limit* determines the buffer size limit used by the returned `Stream`
76+
instance. By default the *limit* is set to 64 KiB.
77+
78+
The rest of the arguments are passed directly to `loop.create_connection()`.
79+
"""
7380
# Design note:
7481
# Don't use decorator approach but explicit non-async
7582
# function to fail fast and explicitly
@@ -108,6 +115,13 @@ async def _connect(host, port,
108115

109116

110117
def connect_read_pipe(pipe, *, limit=_DEFAULT_LIMIT):
118+
"""Establish a connection to a file-like object *pipe* to receive data.
119+
120+
Takes a file-like object *pipe* to return a Stream object of the mode
121+
StreamMode.READ that has similar API of StreamReader. It can also be used
122+
as an async context manager.
123+
"""
124+
111125
# Design note:
112126
# Don't use decorator approach but explicit non-async
113127
# function to fail fast and explicitly
@@ -129,6 +143,13 @@ async def _connect_read_pipe(pipe, limit):
129143

130144

131145
def connect_write_pipe(pipe, *, limit=_DEFAULT_LIMIT):
146+
"""Establish a connection to a file-like object *pipe* to send data.
147+
148+
Takes a file-like object *pipe* to return a Stream object of the mode
149+
StreamMode.WRITE that has similar API of StreamWriter. It can also be used
150+
as an async context manager.
151+
"""
152+
132153
# Design note:
133154
# Don't use decorator approach but explicit non-async
134155
# function to fail fast and explicitly

0 commit comments

Comments
 (0)