Skip to content

Commit 9d11bda

Browse files
committed
Fix memoryview.cast over sliced memoryview
Fixes #4758
1 parent f2bfced commit 9d11bda

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

ports/unix/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
716716
}
717717

718718
#if !MICROPY_VFS
719-
uint mp_import_stat(const char *path) {
719+
mp_import_stat_t mp_import_stat(const char *path) {
720720
struct stat st;
721721
if (stat(path, &st) == 0) {
722722
if (S_ISDIR(st.st_mode)) {

py/objarray.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,12 +254,14 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args,
254254
STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_in) {
255255
mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in);
256256
const char *typecode = mp_obj_str_get_str(typecode_in);
257-
size_t element_size = mp_binary_get_size('@', typecode[0], NULL);
258-
size_t bytelen = self->len * mp_binary_get_size('@', self->typecode & ~MP_OBJ_ARRAY_TYPECODE_FLAG_RW, NULL);
259-
if (bytelen % element_size != 0) {
257+
size_t new_element_size = mp_binary_get_size('@', typecode[0], NULL);
258+
size_t old_element_size = mp_binary_get_size('@', self->typecode & ~MP_OBJ_ARRAY_TYPECODE_FLAG_RW, NULL);
259+
size_t bytelen = self->len * old_element_size;
260+
if (bytelen % new_element_size != 0) {
260261
mp_raise_TypeError(MP_ERROR_TEXT("memoryview: length is not a multiple of itemsize"));
261262
}
262-
mp_obj_array_t *result = MP_OBJ_TO_PTR(mp_obj_new_memoryview(*typecode, bytelen / element_size, self->items));
263+
mp_obj_array_t *result = MP_OBJ_TO_PTR(mp_obj_new_memoryview(*typecode, bytelen / new_element_size, self->items));
264+
result->memview_offset = (self->memview_offset * old_element_size) / new_element_size;
263265

264266
// test if the object can be written to
265267
if (self->typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW) {

tests/basics/memoryview_cast.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
try:
2+
memoryview(b'a').cast
3+
except:
4+
print("SKIP")
5+
raise SystemExit
6+
7+
b = bytearray(range(16))
8+
9+
def print_memview(mv):
10+
print(", ".join(hex(v) for v in mv))
11+
12+
mv = memoryview(b)
13+
print_memview(mv)
14+
print_memview(mv[4:])
15+
16+
words = mv.cast("I")
17+
print_memview(words)
18+
print_memview(mv[4:].cast("I"))
19+
print_memview(words[1:])
20+
21+
print_memview(words.cast("B"))

0 commit comments

Comments
 (0)