From: Antoine Pitrou Date: Wed, 5 Sep 2012 18:11:49 +0000 (+0200) Subject: Issue #15841: The readable(), writable() and seekable() methods of BytesIO X-Git-Tag: v3.2.4rc1~570 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1d857453b7065dafdc34a72c1bbb2a993782b383;p=thirdparty%2FPython%2Fcpython.git Issue #15841: The readable(), writable() and seekable() methods of BytesIO and StringIO objects now raise ValueError when the object has been closed. Patch by Alessandro Moura. --- diff --git a/Lib/_pyio.py b/Lib/_pyio.py index a2faeb32579b..2d376d83002d 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -889,12 +889,18 @@ class BytesIO(BufferedIOBase): return pos def readable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return True def writable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return True def seekable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return True @@ -1567,6 +1573,8 @@ class TextIOWrapper(TextIOBase): return self._buffer def seekable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return self._seekable def readable(self): diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 92480989acaa..7c0c84f0d950 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -318,9 +318,9 @@ class MemoryTestMixin: self.assertEqual(memio.isatty(), False) self.assertEqual(memio.closed, False) memio.close() - self.assertEqual(memio.writable(), True) - self.assertEqual(memio.readable(), True) - self.assertEqual(memio.seekable(), True) + self.assertRaises(ValueError, memio.writable) + self.assertRaises(ValueError, memio.readable) + self.assertRaises(ValueError, memio.seekable) self.assertRaises(ValueError, memio.isatty) self.assertEqual(memio.closed, True) @@ -665,7 +665,6 @@ class CBytesIOTest(PyBytesIOTest): check(io.BytesIO(b'a'), basesize + 1 + 1 ) check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) - class CStringIOTest(PyStringIOTest): ioclass = io.StringIO UnsupportedOperation = io.UnsupportedOperation diff --git a/Misc/ACKS b/Misc/ACKS index f534143cb601..5df7962c489c 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -658,6 +658,7 @@ Skip Montanaro Paul Moore Derek Morr James A Morrison +Alessandro Moura Pablo Mouzo Mher Movsisyan Ruslan Mstoi diff --git a/Misc/NEWS b/Misc/NEWS index 93b679b37ffb..3e75f44b856f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -115,6 +115,10 @@ Core and Builtins Library ------- +- Issue #15841: The readable(), writable() and seekable() methods of BytesIO + and StringIO objects now raise ValueError when the object has been closed. + Patch by Alessandro Moura. + - Issue #15509: webbrowser.UnixBrowser no longer passes empty arguments to Popen when %action substitutions produce empty strings. diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 03f4c7d14aad..ef951aaa031e 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -121,7 +121,7 @@ resize_buffer(bytesio *self, size_t size) } /* Internal routine for writing a string of bytes to the buffer of a BytesIO - object. Returns the number of bytes wrote, or -1 on error. */ + object. Returns the number of bytes written, or -1 on error. */ static Py_ssize_t write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) { @@ -171,10 +171,20 @@ bytesio_get_closed(bytesio *self) } } +PyDoc_STRVAR(readable_doc, +"readable() -> bool. Returns True if the IO object can be read."); + +PyDoc_STRVAR(writable_doc, +"writable() -> bool. Returns True if the IO object can be written."); + +PyDoc_STRVAR(seekable_doc, +"seekable() -> bool. Returns True if the IO object can be seeked."); + /* Generic getter for the writable, readable and seekable properties */ static PyObject * -return_true(bytesio *self) +return_not_closed(bytesio *self) { + CHECK_CLOSED(self); Py_RETURN_TRUE; } @@ -867,9 +877,9 @@ static PyGetSetDef bytesio_getsetlist[] = { }; static struct PyMethodDef bytesio_methods[] = { - {"readable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"writable", (PyCFunction)return_true, METH_NOARGS, NULL}, + {"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc}, + {"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc}, + {"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc}, {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc}, {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc}, {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc}, diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index c9d14b114b18..1f1fa40b02d7 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -650,10 +650,21 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds) } /* Properties and pseudo-properties */ + +PyDoc_STRVAR(stringio_readable_doc, +"readable() -> bool. Returns True if the IO object can be read."); + +PyDoc_STRVAR(stringio_writable_doc, +"writable() -> bool. Returns True if the IO object can be written."); + +PyDoc_STRVAR(stringio_seekable_doc, +"seekable() -> bool. Returns True if the IO object can be seeked."); + static PyObject * stringio_seekable(stringio *self, PyObject *args) { CHECK_INITIALIZED(self); + CHECK_CLOSED(self); Py_RETURN_TRUE; } @@ -661,6 +672,7 @@ static PyObject * stringio_readable(stringio *self, PyObject *args) { CHECK_INITIALIZED(self); + CHECK_CLOSED(self); Py_RETURN_TRUE; } @@ -668,6 +680,7 @@ static PyObject * stringio_writable(stringio *self, PyObject *args) { CHECK_INITIALIZED(self); + CHECK_CLOSED(self); Py_RETURN_TRUE; } @@ -835,9 +848,9 @@ static struct PyMethodDef stringio_methods[] = { {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc}, {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc}, - {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS}, - {"readable", (PyCFunction)stringio_readable, METH_NOARGS}, - {"writable", (PyCFunction)stringio_writable, METH_NOARGS}, + {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc}, + {"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc}, + {"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc}, {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS}, {"__setstate__", (PyCFunction)stringio_setstate, METH_O},