Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1d85745

Browse files
committed
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.
1 parent 397e5c9 commit 1d85745

6 files changed

Lines changed: 47 additions & 12 deletions

File tree

Lib/_pyio.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,12 +889,18 @@ def truncate(self, pos=None):
889889
return pos
890890

891891
def readable(self):
892+
if self.closed:
893+
raise ValueError("I/O operation on closed file.")
892894
return True
893895

894896
def writable(self):
897+
if self.closed:
898+
raise ValueError("I/O operation on closed file.")
895899
return True
896900

897901
def seekable(self):
902+
if self.closed:
903+
raise ValueError("I/O operation on closed file.")
898904
return True
899905

900906

@@ -1567,6 +1573,8 @@ def buffer(self):
15671573
return self._buffer
15681574

15691575
def seekable(self):
1576+
if self.closed:
1577+
raise ValueError("I/O operation on closed file.")
15701578
return self._seekable
15711579

15721580
def readable(self):

Lib/test/test_memoryio.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ def test_flags(self):
318318
self.assertEqual(memio.isatty(), False)
319319
self.assertEqual(memio.closed, False)
320320
memio.close()
321-
self.assertEqual(memio.writable(), True)
322-
self.assertEqual(memio.readable(), True)
323-
self.assertEqual(memio.seekable(), True)
321+
self.assertRaises(ValueError, memio.writable)
322+
self.assertRaises(ValueError, memio.readable)
323+
self.assertRaises(ValueError, memio.seekable)
324324
self.assertRaises(ValueError, memio.isatty)
325325
self.assertEqual(memio.closed, True)
326326

@@ -665,7 +665,6 @@ def test_sizeof(self):
665665
check(io.BytesIO(b'a'), basesize + 1 + 1 )
666666
check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
667667

668-
669668
class CStringIOTest(PyStringIOTest):
670669
ioclass = io.StringIO
671670
UnsupportedOperation = io.UnsupportedOperation

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ Skip Montanaro
658658
Paul Moore
659659
Derek Morr
660660
James A Morrison
661+
Alessandro Moura
661662
Pablo Mouzo
662663
Mher Movsisyan
663664
Ruslan Mstoi

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ Core and Builtins
115115
Library
116116
-------
117117

118+
- Issue #15841: The readable(), writable() and seekable() methods of BytesIO
119+
and StringIO objects now raise ValueError when the object has been closed.
120+
Patch by Alessandro Moura.
121+
118122
- Issue #15509: webbrowser.UnixBrowser no longer passes empty arguments to
119123
Popen when %action substitutions produce empty strings.
120124

Modules/_io/bytesio.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ resize_buffer(bytesio *self, size_t size)
121121
}
122122

123123
/* Internal routine for writing a string of bytes to the buffer of a BytesIO
124-
object. Returns the number of bytes wrote, or -1 on error. */
124+
object. Returns the number of bytes written, or -1 on error. */
125125
static Py_ssize_t
126126
write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
127127
{
@@ -171,10 +171,20 @@ bytesio_get_closed(bytesio *self)
171171
}
172172
}
173173

174+
PyDoc_STRVAR(readable_doc,
175+
"readable() -> bool. Returns True if the IO object can be read.");
176+
177+
PyDoc_STRVAR(writable_doc,
178+
"writable() -> bool. Returns True if the IO object can be written.");
179+
180+
PyDoc_STRVAR(seekable_doc,
181+
"seekable() -> bool. Returns True if the IO object can be seeked.");
182+
174183
/* Generic getter for the writable, readable and seekable properties */
175184
static PyObject *
176-
return_true(bytesio *self)
185+
return_not_closed(bytesio *self)
177186
{
187+
CHECK_CLOSED(self);
178188
Py_RETURN_TRUE;
179189
}
180190

@@ -867,9 +877,9 @@ static PyGetSetDef bytesio_getsetlist[] = {
867877
};
868878

869879
static struct PyMethodDef bytesio_methods[] = {
870-
{"readable", (PyCFunction)return_true, METH_NOARGS, NULL},
871-
{"seekable", (PyCFunction)return_true, METH_NOARGS, NULL},
872-
{"writable", (PyCFunction)return_true, METH_NOARGS, NULL},
880+
{"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc},
881+
{"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc},
882+
{"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc},
873883
{"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc},
874884
{"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc},
875885
{"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc},

Modules/_io/stringio.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,24 +650,37 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
650650
}
651651

652652
/* Properties and pseudo-properties */
653+
654+
PyDoc_STRVAR(stringio_readable_doc,
655+
"readable() -> bool. Returns True if the IO object can be read.");
656+
657+
PyDoc_STRVAR(stringio_writable_doc,
658+
"writable() -> bool. Returns True if the IO object can be written.");
659+
660+
PyDoc_STRVAR(stringio_seekable_doc,
661+
"seekable() -> bool. Returns True if the IO object can be seeked.");
662+
653663
static PyObject *
654664
stringio_seekable(stringio *self, PyObject *args)
655665
{
656666
CHECK_INITIALIZED(self);
667+
CHECK_CLOSED(self);
657668
Py_RETURN_TRUE;
658669
}
659670

660671
static PyObject *
661672
stringio_readable(stringio *self, PyObject *args)
662673
{
663674
CHECK_INITIALIZED(self);
675+
CHECK_CLOSED(self);
664676
Py_RETURN_TRUE;
665677
}
666678

667679
static PyObject *
668680
stringio_writable(stringio *self, PyObject *args)
669681
{
670682
CHECK_INITIALIZED(self);
683+
CHECK_CLOSED(self);
671684
Py_RETURN_TRUE;
672685
}
673686

@@ -835,9 +848,9 @@ static struct PyMethodDef stringio_methods[] = {
835848
{"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
836849
{"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
837850

838-
{"seekable", (PyCFunction)stringio_seekable, METH_NOARGS},
839-
{"readable", (PyCFunction)stringio_readable, METH_NOARGS},
840-
{"writable", (PyCFunction)stringio_writable, METH_NOARGS},
851+
{"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc},
852+
{"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc},
853+
{"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc},
841854

842855
{"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
843856
{"__setstate__", (PyCFunction)stringio_setstate, METH_O},

0 commit comments

Comments
 (0)