@@ -53,15 +53,35 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice
5353 mp_int_t start , stop ;
5454 mp_obj_slice_get (slice , & ostart , & ostop , & ostep );
5555
56+ if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT (1 )) {
57+ indexes -> step = mp_obj_get_int (ostep );
58+ if (indexes -> step == 0 ) {
59+ mp_raise_ValueError ("slice step cannot be zero" );
60+ }
61+ } else {
62+ indexes -> step = 1 ;
63+ }
64+
5665 if (ostart == mp_const_none ) {
57- start = 0 ;
66+ if (indexes -> step > 0 ) {
67+ start = 0 ;
68+ } else {
69+ start = len - 1 ;
70+ }
5871 } else {
5972 start = mp_obj_get_int (ostart );
6073 }
6174 if (ostop == mp_const_none ) {
62- stop = len ;
75+ if (indexes -> step > 0 ) {
76+ stop = len ;
77+ } else {
78+ stop = 0 ;
79+ }
6380 } else {
6481 stop = mp_obj_get_int (ostop );
82+ if (stop >= 0 && indexes -> step < 0 ) {
83+ stop += 1 ;
84+ }
6585 }
6686
6787 // 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
7090 if (start < 0 ) {
7191 start = 0 ;
7292 }
73- } else if ((mp_uint_t )start > len ) {
93+ } else if (indexes -> step > 0 && (mp_uint_t )start > len ) {
7494 start = len ;
95+ } else if (indexes -> step < 0 && (mp_uint_t )start > len - 1 ) {
96+ start = len - 1 ;
7597 }
7698 if (stop < 0 ) {
7799 stop = len + stop ;
100+ if (indexes -> step < 0 ) {
101+ stop += 1 ;
102+ }
78103 } else if ((mp_uint_t )stop > len ) {
79104 stop = len ;
80105 }
81106
82107 // CPython returns empty sequence in such case, or point for assignment is at start
83- if (start > stop ) {
108+ if (indexes -> step > 0 && start > stop ) {
84109 stop = start ;
110+ } else if (indexes -> step < 0 && start < stop ) {
111+ stop = start + 1 ;
85112 }
86113
87114 indexes -> start = start ;
88115 indexes -> stop = stop ;
89116
90- if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT (1 )) {
91- indexes -> step = mp_obj_get_int (ostep );
92- return false;
93- }
94- indexes -> step = 1 ;
95- return true;
117+ return indexes -> step == 1 ;
96118}
97119
98120#endif
@@ -106,10 +128,9 @@ mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice
106128 mp_obj_t res = mp_obj_new_list (0 , NULL );
107129
108130 if (step < 0 ) {
109- stop -- ;
110- while (start <= stop ) {
111- mp_obj_list_append (res , seq [stop ]);
112- stop += step ;
131+ while (start >= stop ) {
132+ mp_obj_list_append (res , seq [start ]);
133+ start += step ;
113134 }
114135 } else {
115136 while (start < stop ) {
0 commit comments