Skip to content

Commit 6d2680f

Browse files
committed
py/objarray: Fix constructing a memoryview from a memoryview.
Fixes issue micropython#7261. Signed-off-by: Damien George <damien@micropython.org>
1 parent 1446107 commit 6d2680f

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

py/objarray.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args,
220220
bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL),
221221
bufinfo.buf));
222222

223+
// If the input object is a memoryview then need to point the items of the
224+
// new memoryview to the start of the buffer so the GC can trace it.
225+
if (mp_obj_get_type(args[0]) == &mp_type_memoryview) {
226+
mp_obj_array_t *other = MP_OBJ_TO_PTR(args[0]);
227+
self->memview_offset = other->memview_offset;
228+
self->items = other->items;
229+
}
230+
223231
// test if the object can be written to
224232
if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) {
225233
self->typecode |= MP_OBJ_ARRAY_TYPECODE_FLAG_RW; // indicate writable buffer

tests/basics/memoryview_gc.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,13 @@
2121

2222
# check that the memoryview is still what we want
2323
print(list(m))
24+
25+
# check that creating a memoryview of a memoryview retains the underlying data
26+
m = None
27+
gc.collect() # cleanup from previous test
28+
m = memoryview(memoryview(bytearray(i for i in range(50)))[5:-5])
29+
print(sum(m), list(m[:10]))
30+
gc.collect()
31+
for i in range(10):
32+
list(range(10)) # allocate memory to overwrite any reclaimed heap
33+
print(sum(m), list(m[:10]))

0 commit comments

Comments
 (0)