Skip to content

Commit b6b7d64

Browse files
jeplerdpgeorge
authored andcommitted
py/modio: Fix the case where write fails in BufferedWriter.flush.
Previously, there was no test coverage of the "write failed" path. In fact, the assertion would fire instead of gracefully raising a Python exception. Slightly re-organize the code to place the assertion later. Add a test case which exercises all paths, and update the expected output. Signed-off-by: Jeff Epler <[email protected]>
1 parent 5ade8b7 commit b6b7d64

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

py/modio.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,13 @@ static mp_obj_t bufwriter_flush(mp_obj_t self_in) {
169169
int err;
170170
mp_uint_t out_sz = mp_stream_write_exactly(self->stream, self->buf, self->len, &err);
171171
(void)out_sz;
172-
// TODO: try to recover from a case of non-blocking stream, e.g. move
173-
// remaining chunk to the beginning of buffer.
174-
assert(out_sz == self->len);
175-
self->len = 0;
176172
if (err != 0) {
177173
mp_raise_OSError(err);
174+
} else {
175+
// TODO: try to recover from a case of non-blocking stream, e.g. move
176+
// remaining chunk to the beginning of buffer.
177+
assert(out_sz == self->len);
178+
self->len = 0;
178179
}
179180
}
180181

tests/basics/io_buffered_writer.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,27 @@
2828

2929
# hashing a BufferedWriter
3030
print(type(hash(buf)))
31+
32+
# Test failing flush()
33+
class MyIO(io.IOBase):
34+
def __init__(self):
35+
self.count = 0
36+
37+
def write(self, buf):
38+
self.count += 1
39+
if self.count < 3:
40+
return None
41+
print("writing", buf)
42+
return len(buf)
43+
44+
45+
buf = io.BufferedWriter(MyIO(), 8)
46+
47+
buf.write(b"foobar")
48+
49+
for _ in range(4):
50+
try:
51+
buf.flush()
52+
print("flushed")
53+
except OSError:
54+
print("OSError")

tests/basics/io_buffered_writer.py.exp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ b'foobarfoobar'
44
b'foobarfoobar'
55
b'foo'
66
<class 'int'>
7+
OSError
8+
OSError
9+
writing bytearray(b'foobar')
10+
flushed
11+
flushed

0 commit comments

Comments
 (0)