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