summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJeff Epler <jepler@gmail.com>2019-12-03 14:50:37 -0600
committerJeff Epler <jepler@gmail.com>2019-12-04 09:29:57 -0600
commit238e12123690debaf2cf8488fb2a4d4003a06506 (patch)
treeb12a6de61a40b29a2baff0d24c09f9e25c960156 /lib
parent15886b1505d854d76e353b9c5261568c7065d2bf (diff)
protocols: Allow them to be (optionally) type-safe
Protocols are nice, but there is no way for C code to verify whether a type's "protocol" structure actually implements some particular protocol. As a result, you can pass an object that implements the "vfs" protocol to one that expects the "stream" protocol, and the opposite of awesomeness ensues. This patch adds an OPTIONAL (but enabled by default) protocol identifier as the first member of any protocol structure. This identifier is simply a unique QSTR chosen by the protocol designer and used by each protocol implementer. When checking for protocol support, instead of just checking whether the object's type has a non-NULL protocol field, use `mp_proto_get` which implements the protocol check when possible. The existing protocols are now named: protocol_framebuf protocol_i2c protocol_pin protocol_stream protocol_spi protocol_vfs (most of these are unused in CP and are just inherited from MP; vfs and stream are definitely used though) I did not find any crashing examples, but here's one to give a flavor of what is improved, using `micropython_coverage`. Before the change, the vfs "ioctl" protocol is invoked, and the result is not intelligible as json (but it could have resulted in a hard fault, potentially): >>> import uos, ujson >>> u = uos.VfsPosix('/tmp') >>> ujson.load(u) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: syntax error in JSON After the change, the vfs object is correctly detected as not supporting the stream protocol: >>> ujson.load(p) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: stream operation not supported
Diffstat (limited to 'lib')
-rw-r--r--lib/utils/sys_stdio_mphal.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/lib/utils/sys_stdio_mphal.c b/lib/utils/sys_stdio_mphal.c
index 266783f37..c1607dfe8 100644
--- a/lib/utils/sys_stdio_mphal.c
+++ b/lib/utils/sys_stdio_mphal.c
@@ -123,6 +123,7 @@ STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
STATIC const mp_stream_p_t stdio_obj_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stdio_read,
.write = stdio_write,
.ioctl = stdio_ioctl,
@@ -158,6 +159,7 @@ STATIC mp_uint_t stdio_buffer_write(mp_obj_t self_in, const void *buf, mp_uint_t
}
STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stdio_buffer_read,
.write = stdio_buffer_write,
.is_text = false,