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

Skip to content

Commit 11946fb

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.
2 parents e8677c0 + 1d85745 commit 11946fb

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
@@ -895,12 +895,18 @@ def truncate(self, pos=None):
895895
return pos
896896

897897
def readable(self):
898+
if self.closed:
899+
raise ValueError("I/O operation on closed file.")
898900
return True
899901

900902
def writable(self):
903+
if self.closed:
904+
raise ValueError("I/O operation on closed file.")
901905
return True
902906

903907
def seekable(self):
908+
if self.closed:
909+
raise ValueError("I/O operation on closed file.")
904910
return True
905911

906912

@@ -1562,6 +1568,8 @@ def buffer(self):
15621568
return self._buffer
15631569

15641570
def seekable(self):
1571+
if self.closed:
1572+
raise ValueError("I/O operation on closed file.")
15651573
return self._seekable
15661574

15671575
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
@@ -731,6 +731,7 @@ Paul Moore
731731
Derek Morr
732732
James A Morrison
733733
Derek McTavish Mounce
734+
Alessandro Moura
734735
Pablo Mouzo
735736
Mher Movsisyan
736737
Ruslan Mstoi

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ Core and Builtins
2121
Library
2222
-------
2323

24+
- Issue #15841: The readable(), writable() and seekable() methods of BytesIO
25+
and StringIO objects now raise ValueError when the object has been closed.
26+
Patch by Alessandro Moura.
27+
2428
- Issue #15447: Use subprocess.DEVNULL in webbrowser, instead of opening
2529
os.devnull explicitly and leaving it open.
2630

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
@@ -760,24 +760,37 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
760760
}
761761

762762
/* Properties and pseudo-properties */
763+
764+
PyDoc_STRVAR(stringio_readable_doc,
765+
"readable() -> bool. Returns True if the IO object can be read.");
766+
767+
PyDoc_STRVAR(stringio_writable_doc,
768+
"writable() -> bool. Returns True if the IO object can be written.");
769+
770+
PyDoc_STRVAR(stringio_seekable_doc,
771+
"seekable() -> bool. Returns True if the IO object can be seeked.");
772+
763773
static PyObject *
764774
stringio_seekable(stringio *self, PyObject *args)
765775
{
766776
CHECK_INITIALIZED(self);
777+
CHECK_CLOSED(self);
767778
Py_RETURN_TRUE;
768779
}
769780

770781
static PyObject *
771782
stringio_readable(stringio *self, PyObject *args)
772783
{
773784
CHECK_INITIALIZED(self);
785+
CHECK_CLOSED(self);
774786
Py_RETURN_TRUE;
775787
}
776788

777789
static PyObject *
778790
stringio_writable(stringio *self, PyObject *args)
779791
{
780792
CHECK_INITIALIZED(self);
793+
CHECK_CLOSED(self);
781794
Py_RETURN_TRUE;
782795
}
783796

@@ -956,9 +969,9 @@ static struct PyMethodDef stringio_methods[] = {
956969
{"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
957970
{"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
958971

959-
{"seekable", (PyCFunction)stringio_seekable, METH_NOARGS},
960-
{"readable", (PyCFunction)stringio_readable, METH_NOARGS},
961-
{"writable", (PyCFunction)stringio_writable, METH_NOARGS},
972+
{"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc},
973+
{"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc},
974+
{"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc},
962975

963976
{"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
964977
{"__setstate__", (PyCFunction)stringio_setstate, METH_O},

0 commit comments

Comments
 (0)