[Python-checkins] cpython (merge 3.4 -> default): Issue #23099: Closing io.BytesIO with exported buffer is rejected now to

serhiy.storchaka python-checkins at python.org
Tue Feb 3 08:31:44 CET 2015


https://hg.python.org/cpython/rev/b9d4c013b09a
changeset:   94481:b9d4c013b09a
parent:      94479:4cb316fe6bf2
parent:      94480:e62d54128bd3
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Feb 03 09:30:51 2015 +0200
summary:
  Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
prevent corrupting exported buffer.

files:
  Doc/library/io.rst        |  13 +++++++------
  Lib/_pyio.py              |   6 ++++++
  Lib/test/test_memoryio.py |   7 ++++++-
  Misc/NEWS                 |   3 +++
  Modules/_io/bytesio.c     |   1 +
  5 files changed, 23 insertions(+), 7 deletions(-)


diff --git a/Doc/library/io.rst b/Doc/library/io.rst
--- a/Doc/library/io.rst
+++ b/Doc/library/io.rst
@@ -578,7 +578,8 @@
 .. class:: BytesIO([initial_bytes])
 
    A stream implementation using an in-memory bytes buffer.  It inherits
-   :class:`BufferedIOBase`.
+   :class:`BufferedIOBase`.  The buffer is discarded when the
+   :meth:`~IOBase.close` method is called.
 
    The argument *initial_bytes* contains optional initial :class:`bytes` data.
 
@@ -599,7 +600,7 @@
 
       .. note::
          As long as the view exists, the :class:`BytesIO` object cannot be
-         resized.
+         resized or closed.
 
       .. versionadded:: 3.2
 
@@ -607,6 +608,7 @@
 
       Return :class:`bytes` containing the entire contents of the buffer.
 
+
    .. method:: read1()
 
       In :class:`BytesIO`, this is the same as :meth:`read`.
@@ -880,7 +882,8 @@
 
 .. class:: StringIO(initial_value='', newline='\\n')
 
-   An in-memory stream for text I/O.
+   An in-memory stream for text I/O.  The text buffer is discarded when the
+   :meth:`~IOBase.close` method is called.
 
    The initial value of the buffer (an empty string by default) can be set by
    providing *initial_value*.  The *newline* argument works like that of
@@ -892,9 +895,7 @@
 
    .. method:: getvalue()
 
-      Return a ``str`` containing the entire contents of the buffer at any
-      time before the :class:`StringIO` object's :meth:`close` method is
-      called.
+      Return a ``str`` containing the entire contents of the buffer.
 
    Example usage::
 
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -852,8 +852,14 @@
     def getbuffer(self):
         """Return a readable and writable view of the buffer.
         """
+        if self.closed:
+            raise ValueError("getbuffer on closed file")
         return memoryview(self._buffer)
 
+    def close(self):
+        self._buffer.clear()
+        super().close()
+
     def read(self, size=None):
         if self.closed:
             raise ValueError("read from closed file")
diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py
--- a/Lib/test/test_memoryio.py
+++ b/Lib/test/test_memoryio.py
@@ -399,14 +399,19 @@
         # raises a BufferError.
         self.assertRaises(BufferError, memio.write, b'x' * 100)
         self.assertRaises(BufferError, memio.truncate)
+        self.assertRaises(BufferError, memio.close)
+        self.assertFalse(memio.closed)
         # Mutating the buffer updates the BytesIO
         buf[3:6] = b"abc"
         self.assertEqual(bytes(buf), b"123abc7890")
         self.assertEqual(memio.getvalue(), b"123abc7890")
-        # After the buffer gets released, we can resize the BytesIO again
+        # After the buffer gets released, we can resize and close the BytesIO
+        # again
         del buf
         support.gc_collect()
         memio.truncate()
+        memio.close()
+        self.assertRaises(ValueError, memio.getbuffer)
 
 
 class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -232,6 +232,9 @@
 Library
 -------
 
+- Issue #23099: Closing io.BytesIO with exported buffer is rejected now to
+  prevent corrupting exported buffer.
+
 - Issue #23326: Removed __ne__ implementations.  Since fixing default __ne__
   implementation in issue #21408 they are redundant.
 
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -779,6 +779,7 @@
 static PyObject *
 bytesio_close(bytesio *self)
 {
+    CHECK_EXPORTS(self);
     reset(self);
     Py_RETURN_NONE;
 }

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list