[Python-checkins] bpo-35950: Raise UnsupportedOperation in BufferedReader.truncate() (GH-18586)
Berker Peksag
webhook-mailer at python.org
Fri Feb 21 12:57:34 EST 2020
https://github.com/python/cpython/commit/fd5116c0e77aec05f67fb24f10562ac920648035
commit: fd5116c0e77aec05f67fb24f10562ac920648035
branch: master
author: Berker Peksag <berker.peksag at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-02-21T09:57:26-08:00
summary:
bpo-35950: Raise UnsupportedOperation in BufferedReader.truncate() (GH-18586)
The truncate() method of io.BufferedReader() should raise
UnsupportedOperation when it is called on a read-only
io.BufferedReader() instance.
https://bugs.python.org/issue35950
Automerge-Triggered-By: @methane
files:
A Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst
M Lib/_pyio.py
M Lib/test/test_io.py
M Modules/_io/bufferedio.c
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 4c2414672ed56..8eaa114c07c91 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -792,6 +792,9 @@ def tell(self):
return pos
def truncate(self, pos=None):
+ self._checkClosed()
+ self._checkWritable()
+
# Flush the stream. We're mixing buffered I/O with lower-level I/O,
# and a flush may be necessary to synch both views of the current
# file state.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 0bfa4d249e9a6..c27dfd96bc00d 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -1528,6 +1528,13 @@ def test_read_on_closed(self):
self.assertRaises(ValueError, b.peek)
self.assertRaises(ValueError, b.read1, 1)
+ def test_truncate_on_read_only(self):
+ rawio = self.MockFileIO(b"abc")
+ bufio = self.tp(rawio)
+ self.assertFalse(bufio.writable())
+ self.assertRaises(self.UnsupportedOperation, bufio.truncate)
+ self.assertRaises(self.UnsupportedOperation, bufio.truncate, 0)
+
class CBufferedReaderTest(BufferedReaderTest, SizeofTest):
tp = io.BufferedReader
@@ -2372,6 +2379,10 @@ def test_interleaved_readline_write(self):
# You can't construct a BufferedRandom over a non-seekable stream.
test_unseekable = None
+ # writable() returns True, so there's no point to test it over
+ # a writable stream.
+ test_truncate_on_read_only = None
+
class CBufferedRandomTest(BufferedRandomTest, SizeofTest):
tp = io.BufferedRandom
diff --git a/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst b/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst
new file mode 100644
index 0000000000000..92e3b2399238e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-02-21-02-42-41.bpo-35950.9G3-wl.rst
@@ -0,0 +1,2 @@
+Raise :exc:`io.UnsupportedOperation` in :meth:`io.BufferedReader.truncate`
+when it is called on a read-only :class:`io.BufferedReader` instance.
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 6f55577813c9f..a09082c84f8a2 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1315,15 +1315,19 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos)
PyObject *res = NULL;
CHECK_INITIALIZED(self)
+ CHECK_CLOSED(self, "truncate of closed file")
+ if (!self->writable) {
+ return bufferediobase_unsupported("truncate");
+ }
if (!ENTER_BUFFERED(self))
return NULL;
- if (self->writable) {
- res = buffered_flush_and_rewind_unlocked(self);
- if (res == NULL)
- goto end;
- Py_CLEAR(res);
+ res = buffered_flush_and_rewind_unlocked(self);
+ if (res == NULL) {
+ goto end;
}
+ Py_CLEAR(res);
+
res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
if (res == NULL)
goto end;
More information about the Python-checkins
mailing list