@@ -11441,22 +11441,33 @@ os.readinto -> Py_ssize_t
1144111441
1144211442Read 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
1145011455static Py_ssize_t
1145111456os_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