8000 objlist: Implement support for arbitrary (3-arg) slices. · errordeveloper/micropython@5fd5af9 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit 5fd5af9

Browse files
committed
objlist: Implement support for arbitrary (3-arg) slices.
1 parent de4b932 commit 5fd5af9

File tree

7 files changed

+33
-6
lines changed

7 files changed

+33
-6
lines changed

py/obj.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, u
579579
bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2);
580580
mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args);
581581
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
582+
mp_obj_t mp_seq_extract_slice(uint len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
582583
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
583584
#define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte*)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz))
584585
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_t) \

py/objarray.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
178178
}
179179
mp_bound_slice_t slice;
180180
if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
181-
assert(0);
181+
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
182+
"Only slices with step=1 (aka None) are supported"));
182183
}
183184
mp_obj_array_t *res = array_new(o->typecode, slice.stop - slice.start);
184185
int sz = mp_binary_get_size('@', o->typecode, NULL);

py/objlist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
178178
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
179179
mp_bound_slice_t slice;
180180
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
181-
assert(0);
181+
return mp_seq_extract_slice(self->len, self->items, &slice);
182182
}
183 10000 183
mp_obj_list_t *res = list_new(slice.stop - slice.start);
184184
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);

py/objstr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
353353
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
354354
mp_bound_slice_t slice;
355355
if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) {
356-
assert(0);
356+
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
357+
"Only slices with step=1 (aka None) are supported"));
357358
}
358359
return str_new(type, self_data + slice.start, slice.stop - slice.start);
359360
}

py/objtuple.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
165165
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
166166
mp_bound_slice_t slice;
167167
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
168-
assert(0);
168+
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
169+
"Only slices with step=1 (aka None) are supported"));
169170
}
170171
mp_obj_tuple_t *res = mp_obj_new_tuple(slice.stop - slice.start, NULL);
171172
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);

py/sequence.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,34 @@ bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_
9595
indexes->stop = stop;
9696

9797
if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
98-
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
99-
"Only slices with step=1 (aka None) are supported"));
10098
indexes->step = MP_OBJ_SMALL_INT_VALUE(ostep);
10199
return false;
102100
}
103101
indexes->step = 1;
104102
return true;
105103
}
106104

105+
mp_obj_t mp_seq_extract_slice(uint len, const mp_obj_t *seq, mp_bound_slice_t *indexes) {
106+
machine_int_t start = indexes->start, stop = indexes->stop;
107+
machine_int_t step = indexes->step;
108+
109+
mp_obj_t res = mp_obj_new_list(0, NULL);
110+
111+
if (step < 0) {
112+
stop--;
113+
while (start <= stop) {
114+
mp_obj_list_append(res, seq[stop]);
115+
stop += step;
116+
}
117+
} else {
118+
while (start < stop) {
119+
mp_obj_list_append(res, seq[start]);
120+
start += step;
121+
}
122+
}
123+
return res;
124+
}
125+
107126
// Special-case comparison function for sequences of bytes
108127
// Don't pass MP_BINARY_OP_NOT_EQUAL here
109128
bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2) {

tests/basics/list_slice_3arg.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
x = list(range(10))
2+
print(x[::-1])
3+
print(x[::2])
4+
print(x[::-2])

0 commit comments

Comments
 (0)
0