Skip to content

Commit 923a8a8

Browse files
committed
stream: Handle non-blocking errors in readline() properly.
Just like they handled in other read*(). Note that behavior of readline() in case there's no data when it's called is underspecified in Python lib spec, implemented to behave as read() - return None.
1 parent 0c7b26c commit 923a8a8

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

py/stream.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,24 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
293293

294294
mp_uint_t out_sz = o->type->stream_p->read(o, p, 1, &error);
295295
if (out_sz == MP_STREAM_ERROR) {
296+
if (is_nonblocking_error(error)) {
297+
if (vstr->len == 1) {
298+
// We just incremented it, but otherwise we read nothing
299+
// and immediately got EAGAIN. This is case is not well
300+
// specified in
301+
// https://docs.python.org/3/library/io.html#io.IOBase.readline
302+
// unlike similar case for read(). But we follow the latter's
303+
// behavior - return None.
304+
vstr_free(vstr);
305+
return mp_const_none;
306+
} else {
307+
goto done;
308+
}
309+
}
296310
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(error)));
297311
}
298312
if (out_sz == 0) {
313+
done:
299314
// Back out previously added byte
300315
// Consider, what's better - read a char and get OutOfMemory (so read
301316
// char is lost), or allocate first as we do.

0 commit comments

Comments
 (0)