mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
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.
This commit is contained in:
parent
909f76dab9
commit
6f988b08d1
4 changed files with 23 additions and 8 deletions
|
|
@ -125,6 +125,7 @@ def test_invalid_operations(self):
|
||||||
self.assertRaises(exc, fp.readline)
|
self.assertRaises(exc, fp.readline)
|
||||||
with self.open(os_helper.TESTFN, "wb", buffering=0) as fp:
|
with self.open(os_helper.TESTFN, "wb", buffering=0) as fp:
|
||||||
self.assertRaises(exc, fp.read)
|
self.assertRaises(exc, fp.read)
|
||||||
|
self.assertRaises(exc, fp.readall)
|
||||||
self.assertRaises(exc, fp.readline)
|
self.assertRaises(exc, fp.readline)
|
||||||
with self.open(os_helper.TESTFN, "rb", buffering=0) as fp:
|
with self.open(os_helper.TESTFN, "rb", buffering=0) as fp:
|
||||||
self.assertRaises(exc, fp.write, b"blah")
|
self.assertRaises(exc, fp.write, b"blah")
|
||||||
|
|
|
||||||
|
|
@ -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`
|
||||||
14
Modules/_io/clinic/fileio.c.h
generated
14
Modules/_io/clinic/fileio.c.h
generated
|
|
@ -277,15 +277,19 @@ PyDoc_STRVAR(_io_FileIO_readall__doc__,
|
||||||
"data is available (EAGAIN is returned before bytes are read) returns None.");
|
"data is available (EAGAIN is returned before bytes are read) returns None.");
|
||||||
|
|
||||||
#define _IO_FILEIO_READALL_METHODDEF \
|
#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 *
|
static PyObject *
|
||||||
_io_FileIO_readall_impl(fileio *self);
|
_io_FileIO_readall_impl(fileio *self, PyTypeObject *cls);
|
||||||
|
|
||||||
static PyObject *
|
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__,
|
PyDoc_STRVAR(_io_FileIO_read__doc__,
|
||||||
|
|
@ -543,4 +547,4 @@ _io_FileIO_isatty(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
|
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
|
||||||
#define _IO_FILEIO_TRUNCATE_METHODDEF
|
#define _IO_FILEIO_TRUNCATE_METHODDEF
|
||||||
#endif /* !defined(_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]*/
|
||||||
|
|
|
||||||
|
|
@ -728,6 +728,9 @@ new_buffersize(fileio *self, size_t currentsize)
|
||||||
@permit_long_docstring_body
|
@permit_long_docstring_body
|
||||||
_io.FileIO.readall
|
_io.FileIO.readall
|
||||||
|
|
||||||
|
cls: defining_class
|
||||||
|
/
|
||||||
|
|
||||||
Read all data from the file, returned as bytes.
|
Read all data from the file, returned as bytes.
|
||||||
|
|
||||||
Reads until either there is an error or read() returns size 0 (indicates EOF).
|
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]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_FileIO_readall_impl(fileio *self)
|
_io_FileIO_readall_impl(fileio *self, PyTypeObject *cls)
|
||||||
/*[clinic end generated code: output=faa0292b213b4022 input=10d8b2ec403302dc]*/
|
/*[clinic end generated code: output=d546737ec895c462 input=cecda40bf9961299]*/
|
||||||
{
|
{
|
||||||
Py_off_t pos, end;
|
Py_off_t pos, end;
|
||||||
PyBytesWriter *writer;
|
PyBytesWriter *writer;
|
||||||
|
|
@ -750,6 +753,10 @@ _io_FileIO_readall_impl(fileio *self)
|
||||||
if (self->fd < 0) {
|
if (self->fd < 0) {
|
||||||
return err_closed();
|
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) {
|
if (self->stat_atopen != NULL && self->stat_atopen->st_size < _PY_READ_MAX) {
|
||||||
end = (Py_off_t)self->stat_atopen->st_size;
|
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)
|
if (size < 0)
|
||||||
return _io_FileIO_readall_impl(self);
|
return _io_FileIO_readall_impl(self, cls);
|
||||||
|
|
||||||
if (size > _PY_READ_MAX) {
|
if (size > _PY_READ_MAX) {
|
||||||
size = _PY_READ_MAX;
|
size = _PY_READ_MAX;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue