@@ -373,12 +373,12 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
373373 // Assign
374374 mp_uint_t src_len ;
375375 void * src_items ;
376- size_t item_sz = mp_binary_get_size ('@' , o -> typecode , NULL );
376+ size_t item_sz = mp_binary_get_size ('@' , o -> typecode & TYPECODE_MASK , NULL );
377377 if (MP_OBJ_IS_TYPE (value , & mp_type_array ) || MP_OBJ_IS_TYPE (value , & mp_type_bytearray )) {
378378 mp_obj_array_t * src_slice = value ;
379- if (item_sz != mp_binary_get_size ('@' , src_slice -> typecode , NULL )) {
379+ if (item_sz != mp_binary_get_size ('@' , src_slice -> typecode & TYPECODE_MASK , NULL )) {
380380 compat_error :
381- mp_not_implemented ( "lhs and rhs should be compatible" );
381+ nlr_raise ( mp_obj_new_exception_msg ( & mp_type_ValueError , "lhs and rhs should be compatible" ) );
382382 }
383383 src_len = src_slice -> len ;
384384 src_items = src_slice -> items ;
@@ -390,13 +390,23 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
390390 mp_get_buffer_raise (value , & bufinfo , MP_BUFFER_READ );
391391 src_len = bufinfo .len ;
392392 src_items = bufinfo .buf ;
393+ } else if (MP_OBJ_IS_TYPE (value , & mp_type_memoryview )) {
394+ mp_obj_array_t * src_slice = value ;
395+ if (item_sz != mp_binary_get_size ('@' , src_slice -> typecode & TYPECODE_MASK , NULL )) {
396+ goto compat_error ;
397+ }
398+ src_len = src_slice -> len ;
399+ src_items = (uint8_t * )src_slice -> items + (src_slice -> free * item_sz );
393400 } else {
394401 mp_not_implemented ("array/bytes required on right side" );
395402 }
396403
397404 // TODO: check src/dst compat
398405 mp_int_t len_adj = src_len - (slice .stop - slice .start );
399406 if (len_adj > 0 ) {
407+ if (o -> base .type == & mp_type_memoryview ) {
408+ goto compat_error ;
409+ }
400410 if (len_adj > o -> free ) {
401411 // TODO: alloc policy; at the moment we go conservative
402412 o -> items = m_renew (byte , o -> items , (o -> len + o -> free ) * item_sz , (o -> len + len_adj ) * item_sz );
@@ -405,12 +415,20 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
405415 mp_seq_replace_slice_grow_inplace (o -> items , o -> len ,
406416 slice .start , slice .stop , src_items , src_len , len_adj , item_sz );
407417 } else {
408- mp_seq_replace_slice_no_grow (o -> items , o -> len ,
409- slice .start , slice .stop , src_items , src_len , item_sz );
410- // Clear "freed" elements at the end of list
411- // TODO: This is actually only needed for typecode=='O'
412- mp_seq_clear (o -> items , o -> len + len_adj , o -> len , item_sz );
413- // TODO: alloc policy after shrinking
418+ if (o -> base .type == & mp_type_memoryview ) {
419+ if (len_adj != 0 ) {
420+ goto compat_error ;
421+ }
422+ mp_seq_replace_slice_no_grow ((uint8_t * )o -> items + (o -> free * item_sz ), o -> len ,
423+ slice .start , slice .stop , src_items , src_len , item_sz );
424+ } else {
425+ mp_seq_replace_slice_no_grow (o -> items , o -> len ,
426+ slice .start , slice .stop , src_items , src_len , item_sz );
427+ // Clear "freed" elements at the end of list
428+ // TODO: This is actually only needed for typecode=='O'
429+ mp_seq_clear (o -> items , o -> len + len_adj , o -> len , item_sz );
430+ // TODO: alloc policy after shrinking
431+ }
414432 }
415433 o -> len += len_adj ;
416434 return mp_const_none ;
0 commit comments