Skip to content

Commit 0a98f3a

Browse files
jeplerdpgeorge
authored andcommitted
py/objarray: Allow extending array with any iterable.
As suggested by @dpgeorge, factor out part of array_construct to allow it to be used for construction & extension. Note that extending with a known-length list (or tuple) goes through the slow path of calling array_extend once per element. Fixes issue adafruit#7408. Signed-off-by: Jeff Epler <[email protected]>
1 parent c1629dc commit 0a98f3a

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

py/objarray.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ static mp_obj_array_t *array_new(char typecode, size_t n) {
113113
#endif
114114

115115
#if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
116+
static void array_extend_impl(mp_obj_array_t *array, mp_obj_t arg, char typecode, size_t len) {
117+
mp_obj_t iterable = mp_getiter(arg, NULL);
118+
mp_obj_t item;
119+
size_t i = 0;
120+
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
121+
if (len == 0) {
122+
array_append(MP_OBJ_FROM_PTR(array), item);
123+
} else {
124+
mp_binary_set_val_array(typecode, array->items, i++, item);
125+
}
126+
}
127+
}
128+
116129
static mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
117130
// bytearrays can be raw-initialised from anything with the buffer protocol
118131
// other arrays can only be raw-initialised from bytes and bytearray objects
@@ -142,18 +155,7 @@ static mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
142155
}
143156

144157
mp_obj_array_t *array = array_new(typecode, len);
145-
146-
mp_obj_t iterable = mp_getiter(initializer, NULL);
147-
mp_obj_t item;
148-
size_t i = 0;
149-
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
150-
if (len == 0) {
151-
array_append(MP_OBJ_FROM_PTR(array), item);
152-
} else {
153-
mp_binary_set_val_array(typecode, array->items, i++, item);
154-
}
155-
}
156-
158+
array_extend_impl(array, initializer, typecode, len);
157159
return MP_OBJ_FROM_PTR(array);
158160
}
159161
#endif
@@ -413,7 +415,10 @@ static mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) {
413415

414416
// allow to extend by anything that has the buffer protocol (extension to CPython)
415417
mp_buffer_info_t arg_bufinfo;
416-
mp_get_buffer_raise(arg_in, &arg_bufinfo, MP_BUFFER_READ);
418+
if (!mp_get_buffer(arg_in, &arg_bufinfo, MP_BUFFER_READ)) {
419+
array_extend_impl(self, arg_in, 0, 0);
420+
return mp_const_none;
421+
}
417422

418423
size_t sz = mp_binary_get_size('@', self->typecode, NULL);
419424

tests/basics/array_add.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@
1414

1515
a1.extend(array.array('I', [5]))
1616
print(a1)
17+
18+
a1.extend([6, 7])
19+
print(a1)
20+
21+
a1.extend(i for i in (8, 9))
22+
print(a1)

0 commit comments

Comments
 (0)