]> granicus.if.org Git - python/commitdiff
Issue #15841: The readable(), writable() and seekable() methods of io.BytesIO
authorAntoine Pitrou <solipsis@pitrou.net>
Wed, 5 Sep 2012 18:11:49 +0000 (20:11 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Wed, 5 Sep 2012 18:11:49 +0000 (20:11 +0200)
and io.StringIO objects now raise ValueError when the object has been closed.
Patch by Alessandro Moura.

Lib/_pyio.py
Lib/test/test_memoryio.py
Misc/ACKS
Misc/NEWS
Modules/_io/bytesio.c
Modules/_io/stringio.c

index d5114338fad37808883881cd63658569fd3da36a..86f3c4c883609f09ea98762d243c92cb7f9e0bb0 100644 (file)
@@ -883,12 +883,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
 
 
@@ -1546,6 +1552,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):
index 007a0929af2e6212437e51b1380b539b7a87cfd7..c3d559d6c43667c71078437e127936767329a03f 100644 (file)
@@ -328,9 +328,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)
 
@@ -649,7 +649,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
index 2a93d66d9d776ae1b7c1d8fa3d0111fa6fc68be6..87200ec0441cd93d7cb8de703e2ea0abdeb3dc86 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -602,6 +602,7 @@ Skip Montanaro
 Paul Moore
 Derek Morr
 James A Morrison
+Alessandro Moura
 Pablo Mouzo
 Ruslan Mstoi
 Sjoerd Mullender
index 0a35f0e52704474fbc13b2bb9c508e4d808a0fd3..68e0d6b14c7a302a3973b3fbb2c110bb77dddf8f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -98,6 +98,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #15841: The readable(), writable() and seekable() methods of
+  io.BytesIO and io.StringIO objects now raise ValueError when the object has
+  been closed.  Patch by Alessandro Moura.
+
 - Issue #12776,#11839: call argparse type function (specified by add_argument)
   only once. Before, the type function was called twice in the case where the
   default was specified and the argument was given as well.  This was
index ae8c1c1f0f4e76278763f14545b1d0270ca846e0..64983206477d50cd8533cae36da1fa723c0302ce 100644 (file)
@@ -106,7 +106,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)
 {
@@ -156,10 +156,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;
 }
 
@@ -827,9 +837,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},
index e3de75155d0739fe3ae031d3ffce9a5c240d5cbb..59a3905b011c20eaa106733a3e539780ffdc5a64 100644 (file)
@@ -632,10 +632,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;
 }
 
@@ -643,6 +654,7 @@ static PyObject *
 stringio_readable(stringio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
+    CHECK_CLOSED(self);
     Py_RETURN_TRUE;
 }
 
@@ -650,6 +662,7 @@ static PyObject *
 stringio_writable(stringio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
+    CHECK_CLOSED(self);
     Py_RETURN_TRUE;
 }
 
@@ -817,9 +830,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},