From 90fae9172a67f44e1fac967f628f26ddf90da963 Mon Sep 17 00:00:00 2001 From: stijn Date: Wed, 8 May 2019 16:16:17 +0200 Subject: [PATCH] py/objarray: Add support for memoryview.itemsize attribute. This allows figuring out the number of bytes in the memoryview object as len(memview) * memview.itemsize. The feature is enabled via MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE and is disabled by default. --- ports/unix/mpconfigport_coverage.h | 1 + py/mpconfig.h | 5 +++++ py/objarray.c | 16 ++++++++++++++++ tests/basics/memoryview_itemsize.py | 9 +++++++++ 4 files changed, 31 insertions(+) create mode 100644 tests/basics/memoryview_itemsize.py diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h index f3fbee6bfa..b2f1d6e88e 100644 --- a/ports/unix/mpconfigport_coverage.h +++ b/ports/unix/mpconfigport_coverage.h @@ -40,6 +40,7 @@ #define MICROPY_MODULE_GETATTR (1) #define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (1) #define MICROPY_PY_BUILTINS_NEXT2 (1) #define MICROPY_PY_BUILTINS_RANGE_BINOP (1) #define MICROPY_PY_BUILTINS_HELP (1) diff --git a/py/mpconfig.h b/py/mpconfig.h index 38b36a4b18..2d857d8f6d 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -856,6 +856,11 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_MEMORYVIEW (0) #endif +// Whether to support memoryview.itemsize attribute +#ifndef MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE +#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (0) +#endif + // Whether to support set object #ifndef MICROPY_PY_BUILTINS_SET #define MICROPY_PY_BUILTINS_SET (1) diff --git a/py/objarray.c b/py/objarray.c index 02f6dff528..89d2f21806 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -231,6 +231,19 @@ 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_PY_BUILTINS_MEMORYVIEW_ITEMSIZE +STATIC void memoryview_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + if (dest[0] != MP_OBJ_NULL) { + return; + } + if (attr == MP_QSTR_itemsize) { + mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); + dest[0] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->typecode & TYPECODE_MASK, NULL)); + } +} +#endif + #endif STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { @@ -560,6 +573,9 @@ const mp_obj_type_t mp_type_memoryview = { .getiter = array_iterator_new, .unary_op = array_unary_op, .binary_op = array_binary_op, + #if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE + .attr = memoryview_attr, + #endif .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, }; diff --git a/tests/basics/memoryview_itemsize.py b/tests/basics/memoryview_itemsize.py new file mode 100644 index 0000000000..108c69cfdc --- /dev/null +++ b/tests/basics/memoryview_itemsize.py @@ -0,0 +1,9 @@ +try: + memoryview(b'a').itemsize + from array import array +except: + print("SKIP") + raise SystemExit + +for code in ['b', 'h', 'i', 'l', 'q', 'f', 'd']: + print(memoryview(array(code)).itemsize)