From 646eb9a7db654ebbbb8c1f85ba362a24db0dc77e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 20 Feb 2021 10:35:27 -0600 Subject: [PATCH 1/3] py: memoryview: implement memoryview.cast if CPYTHON_COMPAT --- py/objarray.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/py/objarray.c b/py/objarray.c index e0b4cbd55f..50b87fb11c 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -238,6 +238,24 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, return MP_OBJ_FROM_PTR(self); } + +STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_in) { + mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); + const char *typecode = mp_obj_str_get_str(typecode_in); + size_t element_size = mp_binary_get_size('@', typecode[0], NULL); + size_t bytelen = self->len * mp_binary_get_size('@', self->typecode & ~MP_OBJ_ARRAY_TYPECODE_FLAG_RW, NULL); + if (bytelen % element_size != 0) { + mp_raise_TypeError(translate("memoryview: length is not a multiple of itemsize")); + } + mp_obj_array_t *result = MP_OBJ_TO_PTR(mp_obj_new_memoryview(*typecode, bytelen / element_size, self->items)); + + // test if the object can be written to + if (self->typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW) { + result->typecode |= MP_OBJ_ARRAY_TYPECODE_FLAG_RW; // indicate writable buffer + } + return MP_OBJ_FROM_PTR(result); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(memoryview_cast_obj, memoryview_cast); #endif STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { @@ -691,6 +709,15 @@ const mp_obj_type_t mp_type_bytearray = { #endif #if MICROPY_PY_BUILTINS_MEMORYVIEW + +#if MICROPY_CPYTHON_COMPAT +STATIC const mp_rom_map_elem_t memoryview_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_cast), MP_ROM_PTR(&memoryview_cast_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(memoryview_locals_dict, memoryview_locals_dict_table); +#endif + const mp_obj_type_t mp_type_memoryview = { { &mp_type_type }, .name = MP_QSTR_memoryview, @@ -700,6 +727,9 @@ const mp_obj_type_t mp_type_memoryview = { .binary_op = array_binary_op, .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, +#if MICROPY_CPYTHON_COMPAT + .locals_dict = (mp_obj_dict_t*)&memoryview_locals_dict, +#endif }; #endif From 1a3b12a3bcc460f29c9cb2a5ba5033bc63bfe0ce Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 20 Feb 2021 15:17:38 -0600 Subject: [PATCH 2/3] make translate --- locale/circuitpython.pot | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0a79520b88..f9ef4ad13c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -3337,6 +3337,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" From a04369e0f58623079bc6f1f33f847e5c08b2d587 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 20 Feb 2021 17:41:08 -0600 Subject: [PATCH 3/3] add ifdef-guard --- py/objarray.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py/objarray.c b/py/objarray.c index 50b87fb11c..9640f596a3 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -239,6 +239,7 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, return MP_OBJ_FROM_PTR(self); } +#if MICROPY_CPYTHON_COMPAT STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_in) { mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); const char *typecode = mp_obj_str_get_str(typecode_in); @@ -257,6 +258,7 @@ STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_ } STATIC MP_DEFINE_CONST_FUN_OBJ_2(memoryview_cast_obj, memoryview_cast); #endif +#endif STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);