summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2021-02-17 23:24:11 -0500
committerDan Halbert <halbert@halwitz.org>2021-02-17 23:24:11 -0500
commited49c02feb7e206e962bf8a40cd69771b83e25cf (patch)
tree98b75891eb1956c222bdb1df48dbc31e7d9fbe74 /py
parentc26de0136a0ad746bf0ace600a1a9d3ff428c4c6 (diff)
add timeout; finish up for PR
Diffstat (limited to 'py')
-rw-r--r--py/stream.c32
-rw-r--r--py/stream.h4
2 files changed, 26 insertions, 10 deletions
diff --git a/py/stream.c b/py/stream.c
index ae702bb1b..0813c1d7f 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -99,14 +99,22 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) {
STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte flags) {
// What to do if sz < -1? Python docs don't specify this case.
- // CPython does a readall, but here we silently let negatives through,
- // and they will cause a MemoryError.
+ // CPython does a readall, let's do the same.
mp_int_t sz;
- if (n_args == 1 || args[1] == mp_const_none || ((sz = mp_obj_get_int(args[1])) == -1)) {
- return stream_readall(args[0]);
- }
-
const mp_stream_p_t *stream_p = mp_get_stream(args[0]);
+ if (stream_p->pyserial_read_compatibility) {
+ // Pyserial defaults to sz=1 if not specified.
+ if (n_args == 1) {
+ sz = 1;
+ } else {
+ // Pyserial treats negative size as 0.
+ sz = MAX(0, mp_obj_get_int(args[1]));
+ }
+ } else {
+ if (n_args == 1 || args[1] == mp_const_none || (sz = mp_obj_get_int(args[1])) <= -1) {
+ return stream_readall(args[0]);
+ }
+ }
#if MICROPY_PY_BUILTINS_STR_UNICODE
if (stream_p->is_text) {
@@ -284,7 +292,7 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) {
// https://docs.python.org/3/library/socket.html#socket.socket.recv_into
mp_uint_t len = bufinfo.len;
if (n_args > 2) {
- if (mp_get_stream(args[0])->pyserial_compatibility) {
+ if (mp_get_stream(args[0])->pyserial_readinto_compatibility) {
mp_raise_ValueError(translate("length argument not allowed for this type"));
}
len = mp_obj_get_int(args[2]);
@@ -297,7 +305,10 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) {
mp_uint_t out_sz = mp_stream_read_exactly(args[0], bufinfo.buf, len, &error);
if (error != 0) {
if (mp_is_nonblocking_error(error)) {
- return mp_const_none;
+ // pyserial readinto never returns None, just 0.
+ return mp_get_stream(args[0])->pyserial_dont_return_none_compatibility
+ ? MP_OBJ_NEW_SMALL_INT(0)
+ : mp_const_none;
}
mp_raise_OSError(error);
} else {
@@ -323,7 +334,10 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
// If we read nothing, return None, just like read().
// Otherwise, return data read so far.
if (total_size == 0) {
- return mp_const_none;
+ // pyserial read() never returns None, just b''.
+ return stream_p->pyserial_dont_return_none_compatibility
+ ? mp_const_empty_bytes
+ : mp_const_none;
}
break;
}
diff --git a/py/stream.h b/py/stream.h
index be6b23d40..c05dcfc50 100644
--- a/py/stream.h
+++ b/py/stream.h
@@ -72,7 +72,9 @@ typedef struct _mp_stream_p_t {
mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
mp_uint_t is_text : 1; // default is bytes, set this for text stream
- bool pyserial_compatibility: 1; // adjust API to match pyserial more closely
+ bool pyserial_readinto_compatibility: 1; // Disallow size parameter in readinto()
+ bool pyserial_read_compatibility: 1; // Disallow omitting read(size) size parameter
+ bool pyserial_dont_return_none_compatibility: 1; // Don't return None for read() or readinto()
} mp_stream_p_t;
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj);