https://github.com/python/cpython/commit/6f988b08d122e44848e89c04ad1e10c25d072cc7
commit: 6f988b08d122e44848e89c04ad1e10c25d072cc7
branch: main
author: Cody Maloney <[email protected]>
committer: vstinner <[email protected]>
date: 2025-11-12T10:37:48+01:00
summary:
gh-85524: Raise "UnsupportedOperation" on FileIO.readall (#141214)
io.UnsupportedOperation is a subclass of OSError and recommended by
io.IOBase for this case; matches other read methods on io.FileIO.
files:
A Misc/NEWS.d/next/Library/2025-11-07-12-25-46.gh-issue-85524.9SWFIC.rst
M Lib/test/test_io/test_general.py
M Modules/_io/clinic/fileio.c.h
M Modules/_io/fileio.c
diff --git a/Lib/test/test_io/test_general.py b/Lib/test/test_io/test_general.py
index a1cdd6876c2892..f0677b01ea5ce1 100644
--- a/Lib/test/test_io/test_general.py
+++ b/Lib/test/test_io/test_general.py
@@ -125,6 +125,7 @@ def test_invalid_operations(self):
self.assertRaises(exc, fp.readline)
with self.open(os_helper.TESTFN, "wb", buffering=0) as fp:
self.assertRaises(exc, fp.read)
+ self.assertRaises(exc, fp.readall)
self.assertRaises(exc, fp.readline)
with self.open(os_helper.TESTFN, "rb", buffering=0) as fp:
self.assertRaises(exc, fp.write, b"blah")
diff --git
a/Misc/NEWS.d/next/Library/2025-11-07-12-25-46.gh-issue-85524.9SWFIC.rst
b/Misc/NEWS.d/next/Library/2025-11-07-12-25-46.gh-issue-85524.9SWFIC.rst
new file mode 100644
index 00000000000000..3e4fd1a5897b04
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-11-07-12-25-46.gh-issue-85524.9SWFIC.rst
@@ -0,0 +1,3 @@
+Update ``io.FileIO.readall``, an implementation of
:meth:`io.RawIOBase.readall`,
+to follow :class:`io.IOBase` guidelines and raise
:exc:`io.UnsupportedOperation`
+when a file is in "w" mode rather than :exc:`OSError`
diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h
index 04870b1c890361..96c31ce8d6f415 100644
--- a/Modules/_io/clinic/fileio.c.h
+++ b/Modules/_io/clinic/fileio.c.h
@@ -277,15 +277,19 @@ PyDoc_STRVAR(_io_FileIO_readall__doc__,
"data is available (EAGAIN is returned before bytes are read) returns None.");
#define _IO_FILEIO_READALL_METHODDEF \
- {"readall", (PyCFunction)_io_FileIO_readall, METH_NOARGS,
_io_FileIO_readall__doc__},
+ {"readall", _PyCFunction_CAST(_io_FileIO_readall),
METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_readall__doc__},
static PyObject *
-_io_FileIO_readall_impl(fileio *self);
+_io_FileIO_readall_impl(fileio *self, PyTypeObject *cls);
static PyObject *
-_io_FileIO_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
+_io_FileIO_readall(PyObject *self, PyTypeObject *cls, PyObject *const *args,
Py_ssize_t nargs, PyObject *kwnames)
{
- return _io_FileIO_readall_impl((fileio *)self);
+ if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+ PyErr_SetString(PyExc_TypeError, "readall() takes no arguments");
+ return NULL;
+ }
+ return _io_FileIO_readall_impl((fileio *)self, cls);
}
PyDoc_STRVAR(_io_FileIO_read__doc__,
@@ -543,4 +547,4 @@ _io_FileIO_isatty(PyObject *self, PyObject
*Py_UNUSED(ignored))
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
#define _IO_FILEIO_TRUNCATE_METHODDEF
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
-/*[clinic end generated code: output=1902fac9e39358aa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2e48f3df2f189170 input=a9049054013a1b77]*/
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 2544ff4ea91ec8..5d7741fdd830a5 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -728,6 +728,9 @@ new_buffersize(fileio *self, size_t currentsize)
@permit_long_docstring_body
_io.FileIO.readall
+ cls: defining_class
+ /
+
Read all data from the file, returned as bytes.
Reads until either there is an error or read() returns size 0 (indicates EOF).
@@ -738,8 +741,8 @@ data is available (EAGAIN is returned before bytes are
read) returns None.
[clinic start generated code]*/
static PyObject *
-_io_FileIO_readall_impl(fileio *self)
-/*[clinic end generated code: output=faa0292b213b4022 input=10d8b2ec403302dc]*/
+_io_FileIO_readall_impl(fileio *self, PyTypeObject *cls)
+/*[clinic end generated code: output=d546737ec895c462 input=cecda40bf9961299]*/
{
Py_off_t pos, end;
PyBytesWriter *writer;
@@ -750,6 +753,10 @@ _io_FileIO_readall_impl(fileio *self)
if (self->fd < 0) {
return err_closed();
}
+ if (!self->readable) {
+ _PyIO_State *state = get_io_state_by_cls(cls);
+ return err_mode(state, "reading");
+ }
if (self->stat_atopen != NULL && self->stat_atopen->st_size <
_PY_READ_MAX) {
end = (Py_off_t)self->stat_atopen->st_size;
@@ -873,7 +880,7 @@ _io_FileIO_read_impl(fileio *self, PyTypeObject *cls,
Py_ssize_t size)
}
if (size < 0)
- return _io_FileIO_readall_impl(self);
+ return _io_FileIO_readall_impl(self, cls);
if (size > _PY_READ_MAX) {
size = _PY_READ_MAX;
_______________________________________________
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]