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

Skip to content

Commit c644e7c

Browse files
committed
Issue #21396: Fix TextIOWrapper(..., write_through=True) to not force a flush() on the underlying binary stream.
Patch by akira.
1 parent a83ade1 commit c644e7c

5 files changed

Lines changed: 45 additions & 4 deletions

File tree

Lib/test/test_io.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,38 @@ def test_rawio_write_through(self):
26152615
txt.write('5')
26162616
self.assertEqual(b''.join(raw._write_stack), b'123\n45')
26172617

2618+
def test_bufio_write_through(self):
2619+
# Issue #21396: write_through=True doesn't force a flush()
2620+
# on the underlying binary buffered object.
2621+
flush_called, write_called = [], []
2622+
class BufferedWriter(self.BufferedWriter):
2623+
def flush(self, *args, **kwargs):
2624+
flush_called.append(True)
2625+
return super().flush(*args, **kwargs)
2626+
def write(self, *args, **kwargs):
2627+
write_called.append(True)
2628+
return super().write(*args, **kwargs)
2629+
2630+
rawio = self.BytesIO()
2631+
data = b"a"
2632+
bufio = BufferedWriter(rawio, len(data)*2)
2633+
textio = self.TextIOWrapper(bufio, encoding='ascii',
2634+
write_through=True)
2635+
# write to the buffered io but don't overflow the buffer
2636+
text = data.decode('ascii')
2637+
textio.write(text)
2638+
2639+
# buffer.flush is not called with write_through=True
2640+
self.assertFalse(flush_called)
2641+
# buffer.write *is* called with write_through=True
2642+
self.assertTrue(write_called)
2643+
self.assertEqual(rawio.getvalue(), b"") # no flush
2644+
2645+
write_called = [] # reset
2646+
textio.write(text * 10) # total content is larger than bufio buffer
2647+
self.assertTrue(write_called)
2648+
self.assertEqual(rawio.getvalue(), data * 11) # all flushed
2649+
26182650
def test_read_nonbytes(self):
26192651
# Issue #17106
26202652
# Crash when underlying read() returns non-bytes

Lib/test/test_subprocess.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,7 @@ def test_universal_newlines(self):
786786
stdout=subprocess.PIPE,
787787
universal_newlines=1)
788788
p.stdin.write("line1\n")
789+
p.stdin.flush()
789790
self.assertEqual(p.stdout.readline(), "line1\n")
790791
p.stdin.write("line3\n")
791792
p.stdin.close()

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Jim Ahlstrom
2424
Farhan Ahmad
2525
Matthew Ahrens
2626
Nir Aides
27+
Akira
2728
Yaniv Aknin
2829
Jyrki Alakuijala
2930
Steve Alexander

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ What's New in Python 3.4.1?
77

88
Release date: TBA
99

10+
Library
11+
-------
12+
13+
- Issue #21396: Fix TextIOWrapper(..., write_through=True) to not force a
14+
flush() on the underlying binary stream. Patch by akira.
15+
1016
Tests
1117
-----
1218

Modules/_io/textio.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ textiowrapper_write(textio *self, PyObject *args)
12971297
PyObject *b;
12981298
Py_ssize_t textlen;
12991299
int haslf = 0;
1300-
int needflush = 0;
1300+
int needflush = 0, text_needflush = 0;
13011301

13021302
CHECK_INITIALIZED(self);
13031303

@@ -1331,8 +1331,8 @@ textiowrapper_write(textio *self, PyObject *args)
13311331
}
13321332

13331333
if (self->write_through)
1334-
needflush = 1;
1335-
else if (self->line_buffering &&
1334+
text_needflush = 1;
1335+
if (self->line_buffering &&
13361336
(haslf ||
13371337
PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
13381338
needflush = 1;
@@ -1363,7 +1363,8 @@ textiowrapper_write(textio *self, PyObject *args)
13631363
}
13641364
self->pending_bytes_count += PyBytes_GET_SIZE(b);
13651365
Py_DECREF(b);
1366-
if (self->pending_bytes_count > self->chunk_size || needflush) {
1366+
if (self->pending_bytes_count > self->chunk_size || needflush ||
1367+
text_needflush) {
13671368
if (_textiowrapper_writeflush(self) < 0)
13681369
return NULL;
13691370
}

0 commit comments

Comments
 (0)