From 9d11bda9e8bea0f202165d649849daf63bff4465 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 18 May 2023 13:24:50 -0700 Subject: [PATCH 1/2] Fix memoryview.cast over sliced memoryview Fixes #4758 --- ports/unix/main.c | 2 +- py/objarray.c | 10 ++++++---- tests/basics/memoryview_cast.py | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 tests/basics/memoryview_cast.py diff --git a/ports/unix/main.c b/ports/unix/main.c index 5ebcf9193b..dcc1c68fe6 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -716,7 +716,7 @@ MP_NOINLINE int main_(int argc, char **argv) { } #if !MICROPY_VFS -uint mp_import_stat(const char *path) { +mp_import_stat_t mp_import_stat(const char *path) { struct stat st; if (stat(path, &st) == 0) { if (S_ISDIR(st.st_mode)) { diff --git a/py/objarray.c b/py/objarray.c index 518c3aba52..c4a9e7cec4 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -254,12 +254,14 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, 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) { + size_t new_element_size = mp_binary_get_size('@', typecode[0], NULL); + size_t old_element_size = mp_binary_get_size('@', self->typecode & ~MP_OBJ_ARRAY_TYPECODE_FLAG_RW, NULL); + size_t bytelen = self->len * old_element_size; + if (bytelen % new_element_size != 0) { mp_raise_TypeError(MP_ERROR_TEXT("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)); + mp_obj_array_t *result = MP_OBJ_TO_PTR(mp_obj_new_memoryview(*typecode, bytelen / new_element_size, self->items)); + result->memview_offset = (self->memview_offset * old_element_size) / new_element_size; // test if the object can be written to if (self->typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW) { diff --git a/tests/basics/memoryview_cast.py b/tests/basics/memoryview_cast.py new file mode 100644 index 0000000000..24c04e8e5a --- /dev/null +++ b/tests/basics/memoryview_cast.py @@ -0,0 +1,21 @@ +try: + memoryview(b'a').cast +except: + print("SKIP") + raise SystemExit + +b = bytearray(range(16)) + +def print_memview(mv): + print(", ".join(hex(v) for v in mv)) + +mv = memoryview(b) +print_memview(mv) +print_memview(mv[4:]) + +words = mv.cast("I") +print_memview(words) +print_memview(mv[4:].cast("I")) +print_memview(words[1:]) + +print_memview(words.cast("B")) From 177b98174e82272b45d80e0fa2b8fdd01d5804fc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 18 May 2023 16:24:37 -0700 Subject: [PATCH 2/2] Shrink by combining error messages --- locale/circuitpython.pot | 43 +++++++----------------- ports/atmel-samd/common-hal/busio/UART.c | 6 ++-- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 61fd0d0a6b..bd2d35398f 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -165,11 +165,15 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c py/argcheck.c +#: py/argcheck.c msgid "%q must be %d" msgstr "" #: py/argcheck.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c msgid "%q must be %d-%d" msgstr "" @@ -203,6 +207,7 @@ msgstr "" #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +#: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "" @@ -425,6 +430,7 @@ msgid "Address must be %d bytes long" msgstr "" #: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nrf/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" msgstr "" @@ -608,13 +614,6 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "Brightness must be 0-1.0" -msgstr "" - #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" @@ -927,11 +926,6 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" -#: shared-module/synthio/MidiTrack.c -#, c-format -msgid "Error in MIDI stream at position %d" -msgstr "" - #: extmod/modure.c msgid "Error in regex" msgstr "" @@ -1343,11 +1337,6 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "" -#: shared-module/displayio/Shape.c -#, c-format -msgid "Maximum x value when mirrored is %d" -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1441,6 +1430,10 @@ msgstr "" msgid "Nimble out of memory" msgstr "" +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "No %q pin" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" @@ -1489,14 +1482,12 @@ msgstr "" msgid "No MOSI pin" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "No RX pin" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c @@ -2123,8 +2114,8 @@ msgstr "" msgid "UART de-init" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c msgid "UART init" msgstr "" @@ -4342,18 +4333,10 @@ msgstr "" msgid "wrong output type" msgstr "" -#: shared-module/displayio/Shape.c -msgid "x value out of bounds" -msgstr "" - #: ports/espressif/common-hal/audiobusio/__init__.c msgid "xTaskCreate failed" msgstr "" -#: shared-module/displayio/Shape.c -msgid "y value out of bounds" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index 280e8d10b6..92dbc9757e 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -241,7 +241,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } if (usart_async_init(usart_desc_p, sercom, self->buffer, self->buffer_length, NULL) != ERR_NONE) { - mp_raise_RuntimeError(translate("UART init")); + mp_raise_RuntimeError(NULL); } // usart_async_init() sets a number of defaults based on a prototypical SERCOM @@ -396,7 +396,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { // Read characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { if (self->rx_pin == NO_PIN) { - mp_raise_ValueError(translate("No RX pin")); + mp_raise_ValueError_varg(translate("No %q pin"), MP_QSTR_rx); } // This assignment is only here because the usart_async routines take a *const argument. @@ -453,7 +453,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Write characters. size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { if (self->tx_pin == NO_PIN) { - mp_raise_ValueError(translate("No TX pin")); + mp_raise_ValueError_varg(translate("No %q pin"), MP_QSTR_tx); } // This assignment is only here because the usart_async routines take a *const argument.