Skip to content

Commit c8f5800

Browse files
committed
Iterate on docs, guarantee no negative return
1 parent 62f531c commit c8f5800

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

Doc/library/os.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,15 +1667,21 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
16671667
The *buffer* should be mutable and :term:`bytes-like <bytes-like object>`. On
16681668
success, returns the number of bytes read. Less bytes may be read than the
16691669
size of the buffer. The underlying system call will be retried when
1670-
interrupted by a signal. For other errors, it will not be retried.
1670+
interrupted by a signal. Other errors will not be retried and an error will
1671+
be raised.
1672+
1673+
Returns 0 if the fd is at end of file or if the provided buffer is
1674+
length 0 (can be used to check for errors without reading data). Never
1675+
returns a negative value.
16711676

16721677
.. note::
16731678

16741679
This function is intended for low-level I/O and must be applied to a file
16751680
descriptor as returned by :func:`os.open` or :func:`os.pipe`. To read a
1676-
"file object" returned by the built-in function :func:`open` or by
1677-
:func:`popen` or :func:`fdopen`, or :data:`sys.stdin`, use its
1678-
:meth:`~file.readinto` or :meth:`~file.read`.
1681+
"file object" returned by the built-in function :func:`open`, or
1682+
:data:`sys.stdin`, use its member functions, for example
1683+
:meth:`io.BufferedIOBase.readinto`, :meth:`io.BufferedIOBase.read`, or
1684+
:meth:`io.TextIOBase.read`
16791685

16801686
.. versionadded:: next
16811687

Modules/clinic/posixmodule.c.h

Lines changed: 10 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11441,22 +11441,33 @@ os.readinto -> Py_ssize_t
1144111441
1144211442
Read into a Buffer Protocol object from a file descriptor.
1144311443
11444-
The buffer should be mutable and bytes-like. On success, returns the number of
11445-
bytes read. Less bytes may be read than the size of the buffer. Will retry the
11446-
underlying system call when interrupted by a signal. For other errors, the
11447-
system call will not be retried.
11444+
The buffer should be mutable and bytes-like.
11445+
11446+
On success, returns the number of bytes read. Less bytes may be read than the
11447+
size of the buffer without reaching end of stream. Will retry the underlying
11448+
system call when interrupted by a signal. Other errors will not be retried and
11449+
an error will be raised.
11450+
11451+
Returns 0 if the fd is at end of file or the provided buffer is length 0 (can be
11452+
used to check for errors without reading data). Never returns a negative value.
1144811453
[clinic start generated code]*/
1144911454

1145011455
static Py_ssize_t
1145111456
os_readinto_impl(PyObject *module, int fd, Py_buffer *buffer)
11452-
/*[clinic end generated code: output=8091a3513c683a80 input=2d815e709ab6a85b]*/
11457+
/*[clinic end generated code: output=8091a3513c683a80 input=7485bbbb143bf7e8]*/
1145311458
{
1145411459
if (buffer->len < 0) {
11460+
assert(!PyErr_Occurred());
1145511461
errno = EINVAL;
1145611462
PyErr_SetFromErrno(PyExc_OSError);
1145711463
return -1;
1145811464
}
11459-
return _Py_read(fd, buffer->buf, buffer->len);
11465+
Py_ssize_t result = _Py_read(fd, buffer->buf, buffer->len);
11466+
/* Ensure negative is never returned without an error. Simplifies calling
11467+
code. _Py_read should succeed, possibly reading 0 bytes, _or_ set an
11468+
error. */
11469+
assert(result >= 0 || (result == -1 && PyErr_Occurred()));
11470+
return result;
1146011471
}
1146111472

1146211473
#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \

0 commit comments

Comments
 (0)