py/sequence: Fix reverse slicing of lists.
This commit is contained in:
parent
e429daa572
commit
8908e505ce
|
@ -53,15 +53,35 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice
|
||||||
mp_int_t start, stop;
|
mp_int_t start, stop;
|
||||||
mp_obj_slice_get(slice, &ostart, &ostop, &ostep);
|
mp_obj_slice_get(slice, &ostart, &ostop, &ostep);
|
||||||
|
|
||||||
|
if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
|
||||||
|
indexes->step = mp_obj_get_int(ostep);
|
||||||
|
if (indexes->step == 0) {
|
||||||
|
mp_raise_ValueError("slice step cannot be zero");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
indexes->step = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ostart == mp_const_none) {
|
if (ostart == mp_const_none) {
|
||||||
start = 0;
|
if (indexes->step > 0) {
|
||||||
|
start = 0;
|
||||||
|
} else {
|
||||||
|
start = len - 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
start = mp_obj_get_int(ostart);
|
start = mp_obj_get_int(ostart);
|
||||||
}
|
}
|
||||||
if (ostop == mp_const_none) {
|
if (ostop == mp_const_none) {
|
||||||
stop = len;
|
if (indexes->step > 0) {
|
||||||
|
stop = len;
|
||||||
|
} else {
|
||||||
|
stop = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stop = mp_obj_get_int(ostop);
|
stop = mp_obj_get_int(ostop);
|
||||||
|
if (stop >= 0 && indexes->step < 0) {
|
||||||
|
stop += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlike subscription, out-of-bounds slice indexes are never error
|
// Unlike subscription, out-of-bounds slice indexes are never error
|
||||||
|
@ -70,29 +90,31 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
} else if ((mp_uint_t)start > len) {
|
} else if (indexes->step > 0 && (mp_uint_t)start > len) {
|
||||||
start = len;
|
start = len;
|
||||||
|
} else if (indexes->step < 0 && (mp_uint_t)start > len - 1) {
|
||||||
|
start = len - 1;
|
||||||
}
|
}
|
||||||
if (stop < 0) {
|
if (stop < 0) {
|
||||||
stop = len + stop;
|
stop = len + stop;
|
||||||
|
if (indexes->step < 0) {
|
||||||
|
stop += 1;
|
||||||
|
}
|
||||||
} else if ((mp_uint_t)stop > len) {
|
} else if ((mp_uint_t)stop > len) {
|
||||||
stop = len;
|
stop = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPython returns empty sequence in such case, or point for assignment is at start
|
// CPython returns empty sequence in such case, or point for assignment is at start
|
||||||
if (start > stop) {
|
if (indexes->step > 0 && start > stop) {
|
||||||
stop = start;
|
stop = start;
|
||||||
|
} else if (indexes->step < 0 && start < stop) {
|
||||||
|
stop = start + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexes->start = start;
|
indexes->start = start;
|
||||||
indexes->stop = stop;
|
indexes->stop = stop;
|
||||||
|
|
||||||
if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
|
return indexes->step == 1;
|
||||||
indexes->step = mp_obj_get_int(ostep);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
indexes->step = 1;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,10 +128,9 @@ mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice
|
||||||
mp_obj_t res = mp_obj_new_list(0, NULL);
|
mp_obj_t res = mp_obj_new_list(0, NULL);
|
||||||
|
|
||||||
if (step < 0) {
|
if (step < 0) {
|
||||||
stop--;
|
while (start >= stop) {
|
||||||
while (start <= stop) {
|
mp_obj_list_append(res, seq[start]);
|
||||||
mp_obj_list_append(res, seq[stop]);
|
start += step;
|
||||||
stop += step;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (start < stop) {
|
while (start < stop) {
|
||||||
|
|
|
@ -7,3 +7,22 @@ x = list(range(9))
|
||||||
print(x[::-1])
|
print(x[::-1])
|
||||||
print(x[::2])
|
print(x[::2])
|
||||||
print(x[::-2])
|
print(x[::-2])
|
||||||
|
|
||||||
|
x = list(range(5))
|
||||||
|
print(x[:0:-1])
|
||||||
|
print(x[:1:-1])
|
||||||
|
print(x[:2:-1])
|
||||||
|
print(x[0::-1])
|
||||||
|
print(x[1::-1])
|
||||||
|
print(x[2::-1])
|
||||||
|
|
||||||
|
x = list(range(5))
|
||||||
|
print(x[0:0:-1])
|
||||||
|
print(x[4:4:-1])
|
||||||
|
print(x[5:5:-1])
|
||||||
|
|
||||||
|
x = list(range(10))
|
||||||
|
print(x[-1:-1:-1])
|
||||||
|
print(x[-1:-2:-1])
|
||||||
|
print(x[-1:-11:-1])
|
||||||
|
print(x[-10:-11:-1])
|
||||||
|
|
Loading…
Reference in New Issue