Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: py3.5
Changeset: r91088:15ee4ffa4842
Date: 2017-04-18 19:11 +0200
http://bitbucket.org/pypy/pypy/changeset/15ee4ffa4842/

Log:    CPython Issue #21396: write_through=True doesn't force a flush() on
        the underlying binary buffered object.

diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -801,9 +801,10 @@
             text = space.unicode_w(w_text)
 
         needflush = False
+        text_needflush = False
         if self.write_through:
-            needflush = True
-        elif self.line_buffering and (haslf or text.find(u'\r') >= 0):
+            text_needflush = True
+        if self.line_buffering and (haslf or text.find(u'\r') >= 0):
             needflush = True
 
         # XXX What if we were just reading?
@@ -820,7 +821,8 @@
         self.pending_bytes.append(b)
         self.pending_bytes_count += len(b)
 
-        if self.pending_bytes_count > self.chunk_size or needflush:
+        if (self.pending_bytes_count > self.chunk_size or
+            needflush or text_needflush):
             self._writeflush(space)
 
         if needflush:
diff --git a/pypy/module/_io/test/test_bufferedio.py 
b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -291,6 +291,39 @@
         raises(_io.UnsupportedOperation, bufio.seek, 0)
         raises(_io.UnsupportedOperation, bufio.tell)
 
+    def test_bufio_write_through(self):
+        import _io as io
+        # Issue #21396: write_through=True doesn't force a flush()
+        # on the underlying binary buffered object.
+        flush_called, write_called = [], []
+        class BufferedWriter(io.BufferedWriter):
+            def flush(self, *args, **kwargs):
+                flush_called.append(True)
+                return super().flush(*args, **kwargs)
+            def write(self, *args, **kwargs):
+                write_called.append(True)
+                return super().write(*args, **kwargs)
+
+        rawio = io.BytesIO()
+        data = b"a"
+        bufio = BufferedWriter(rawio, len(data)*2)
+        textio = io.TextIOWrapper(bufio, encoding='ascii',
+                                  write_through=True)
+        # write to the buffered io but don't overflow the buffer
+        text = data.decode('ascii')
+        textio.write(text)
+
+        # buffer.flush is not called with write_through=True
+        assert not flush_called
+        # buffer.write *is* called with write_through=True
+        assert write_called
+        assert rawio.getvalue() == b"" # no flush
+
+        write_called = [] # reset
+        textio.write(text * 10) # total content is larger than bufio buffer
+        assert write_called
+        assert rawio.getvalue() == data * 11 # all flushed
+
 class AppTestBufferedReaderWithThreads(AppTestBufferedReader):
     spaceconfig = dict(usemodules=['_io', 'thread', 'time'])
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to