https://github.com/python/cpython/commit/d8af158eb6e16ee5494b6e16c800f9fe7eee9295
commit: d8af158eb6e16ee5494b6e16c800f9fe7eee9295
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: vstinner <[email protected]>
date: 2026-06-05T12:09:13Z
summary:
[3.15] gh-129011: Update docs for Raw I/O read, readinto, and write (GH-135328)
(#150957)
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 <[email protected]>
Co-authored-by: Serhiy Storchaka <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>
files:
M Doc/library/io.rst
diff --git a/Doc/library/io.rst b/Doc/library/io.rst
index 8c0eed592dd49e..d47b74efe22de9 100644
--- a/Doc/library/io.rst
+++ b/Doc/library/io.rst
@@ -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.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]