]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.15] gh-129011: Update docs for Raw I/O read, readinto, and write (GH-135328) ...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 5 Jun 2026 12:09:13 +0000 (14:09 +0200)
committerGitHub <noreply@github.com>
Fri, 5 Jun 2026 12:09:13 +0000 (12:09 +0000)
gh-129011: Update docs for Raw I/O read, readinto, and write (GH-135328)

Update `RawIOBase` and `FileIO` documentation to match implementation
behavior around `.read`, `.readinto`, `.readall` and `.write`.

In particular:

 - They may make more than one system call (PEP-475)
 - Add warnings if `.write()` requires a wrapping retry loop (see: gh-126606)
    - "Raw I/O" `.write`` may not write all bytes
    - `buffering=0` example results in a "Raw I/O"
(cherry picked from commit e4db68b9c990ed1bb7562094bee2e73f4450d42b)

Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Doc/library/io.rst

index 8c0eed592dd49ed137ed745f5a7bc83e1b55e6af..d47b74efe22de9dce1c9cfb7086563d3d63c032a 100644 (file)
@@ -38,6 +38,7 @@ will raise a :exc:`TypeError`.  So will giving a :class:`bytes` object to the
    Operations that used to raise :exc:`IOError` now raise :exc:`OSError`, since
    :exc:`IOError` is now an alias of :exc:`OSError`.
 
+.. _text-io:
 
 Text I/O
 ^^^^^^^^
@@ -65,6 +66,7 @@ In-memory text streams are also available as :class:`StringIO` objects::
 The text stream API is described in detail in the documentation of
 :class:`TextIOBase`.
 
+.. _binary-io:
 
 Binary I/O
 ^^^^^^^^^^
@@ -103,6 +105,13 @@ stream by opening a file in binary mode with buffering disabled::
 
 The raw stream API is described in detail in the docs of :class:`RawIOBase`.
 
+.. warning::
+   Raw I/O is a low-level interface and methods generally must have their return
+   values checked and be explicitly retried to ensure an operation completes.
+   For instance :meth:`~RawIOBase.write` returns the number of bytes written
+   which may be less than the number of bytes provided (a partial write).
+   High-level I/O objects like :ref:`binary-io` and :ref:`text-io` implement
+   retry behavior.
 
 .. _io-text-encoding:
 
@@ -478,8 +487,11 @@ I/O Base Classes
 
       Read up to *size* bytes from the object and return them.  As a convenience,
       if *size* is unspecified or -1, all bytes until EOF are returned.
-      Otherwise, only one system call is ever made.  Fewer than *size* bytes may
-      be returned if the operating system call returns fewer than *size* bytes.
+
+      Attempts to make only one system call but will retry if interrupted and
+      the signal handler does not raise an exception (see :pep:`475` for the
+      rationale). This means fewer than *size* bytes may be returned if the
+      operating system call returns fewer than *size* bytes.
 
       If 0 bytes are returned, and *size* was not 0, this indicates end of file.
       If the object is in non-blocking mode and no bytes are available,
@@ -493,13 +505,19 @@ I/O Base Classes
       Read and return all the bytes from the stream until EOF, using multiple
       calls to the stream if necessary.
 
+      If ``0`` bytes are returned this indicates end of file. If the object is in
+      non-blocking mode and the underlying :meth:`read` returns ``None``
+      indicating no bytes are available, ``None`` is returned.
+
    .. method:: readinto(b, /)
 
       Read bytes into a pre-allocated, writable
       :term:`bytes-like object` *b*, and return the
       number of bytes read.  For example, *b* might be a :class:`bytearray`.
-      If the object is in non-blocking mode and no bytes
-      are available, ``None`` is returned.
+
+      If ``0`` is returned and ``len(b)`` is not ``0``, this indicates end of file. If
+      the object is in non-blocking mode and no bytes are available, ``None`` is
+      returned.
 
    .. method:: write(b, /)
 
@@ -513,6 +531,13 @@ I/O Base Classes
       this method returns, so the implementation should only access *b*
       during the method call.
 
+      .. warning::
+
+         This function does not ensure all bytes are written or an exception is
+         thrown. Callers may implement that behavior by checking the return
+         value and, if it is less than the length of *b*, looping with additional
+         write calls until all unwritten bytes are written. High-level I/O
+         objects like :ref:`binary-io` and :ref:`text-io` implement retry behavior.
 
 .. class:: BufferedIOBase
 
@@ -641,7 +666,11 @@ Raw File I/O
 .. class:: FileIO(name, mode='r', closefd=True, opener=None)
 
    A raw binary stream representing an OS-level file containing bytes data.  It
-   inherits from :class:`RawIOBase`.
+   inherits from :class:`RawIOBase` and implements its low-level access design.
+   This means :meth:`~RawIOBase.write` does not guarantee all bytes are written
+   and :meth:`~RawIOBase.read` may read less bytes than requested even when more
+   bytes may be present in the underlying file. To get "write all" and
+   "read at least" behavior, use :ref:`binary-io`.
 
    The *name* can be one of two things:
 
@@ -661,10 +690,6 @@ Raw File I/O
    implies writing, so this mode behaves in a similar way to ``'w'``. Add a
    ``'+'`` to the mode to allow simultaneous reading and writing.
 
-   The :meth:`~RawIOBase.read` (when called with a positive argument),
-   :meth:`~RawIOBase.readinto` and :meth:`~RawIOBase.write` methods on this
-   class will only make one system call.
-
    A custom opener can be used by passing a callable as *opener*. The underlying
    file descriptor for the file object is then obtained by calling *opener* with
    (*name*, *flags*). *opener* must return an open file descriptor (passing
@@ -676,6 +701,13 @@ Raw File I/O
    See the :func:`open` built-in function for examples on using the *opener*
    parameter.
 
+   .. warning::
+      :class:`FileIO` is a low-level I/O object and members, such as
+      :meth:`~RawIOBase.read` and :meth:`~RawIOBase.write`, need to have their
+      return values checked explicitly in a retry loop to implement "write all"
+      and "read at least" behavior. High-level I/O objects :ref:`binary-io` and
+      :ref:`text-io` implement retry behavior.
+
    .. versionchanged:: 3.3
       The *opener* parameter was added.
       The ``'x'`` mode was added.