@@ -9,7 +9,7 @@ use crate::common::{
99 rc:: PyRc ,
1010} ;
1111use crate :: function:: { FuncArgs , OptionalArg } ;
12- use crate :: sliceable:: { convert_slice, saturate_range , wrap_index, SequenceIndex } ;
12+ use crate :: sliceable:: { convert_slice, wrap_index, SequenceIndex } ;
1313use crate :: slots:: { AsBuffer , Comparable , Hashable , PyComparisonOp , SlotConstructor } ;
1414use crate :: stdlib:: pystruct:: _struct:: FormatSpec ;
1515use crate :: utils:: Either ;
@@ -19,8 +19,7 @@ use crate::{
1919} ;
2020use crossbeam_utils:: atomic:: AtomicCell ;
2121use itertools:: Itertools ;
22- use num_bigint:: BigInt ;
23- use num_traits:: { One , Signed , ToPrimitive , Zero } ;
22+ use num_traits:: ToPrimitive ;
2423use std:: fmt:: Debug ;
2524use std:: ops:: Deref ;
2625
@@ -255,25 +254,20 @@ impl PyMemoryView {
255254
256255 fn getitem_by_slice ( zelf : PyRef < Self > , slice : PySliceRef , vm : & VirtualMachine ) -> PyResult {
257256 // slicing a memoryview return a new memoryview
258- let start = slice. start_index ( vm) ?;
259- let stop = slice. stop_index ( vm) ?;
260- let step = slice. step_index ( vm) ?. unwrap_or_else ( BigInt :: one) ;
261- if step. is_zero ( ) {
262- return Err ( vm. new_value_error ( "slice step cannot be zero" . to_owned ( ) ) ) ;
263- }
264- let newstep: BigInt = step. clone ( ) * zelf. step ;
265257 let len = zelf. buffer . options . len ;
258+ let ( range, step, is_negative_step) = convert_slice ( & slice, len, vm) ?;
259+ let abs_step = step. unwrap ( ) ;
260+ let step = if is_negative_step {
261+ -( abs_step as isize )
262+ } else {
263+ abs_step as isize
264+ } ;
265+ let newstep = step * zelf. step ;
266266 let itemsize = zelf. buffer . options . itemsize ;
267267
268268 let format_spec = zelf. format_spec . clone ( ) ;
269269
270- if newstep == BigInt :: one ( ) {
271- let range = saturate_range ( & start, & stop, len) ;
272- let range = if range. end < range. start {
273- range. start ..range. start
274- } else {
275- range
276- } ;
270+ if newstep == 1 {
277271 let newlen = range. end - range. start ;
278272 let start = zelf. start + range. start * itemsize;
279273 let stop = zelf. start + range. end * itemsize;
@@ -294,35 +288,7 @@ impl PyMemoryView {
294288 . into_object ( vm) ) ;
295289 }
296290
297- let ( start, stop) = if step. is_negative ( ) {
298- (
299- stop. map ( |x| {
300- if x == -BigInt :: one ( ) {
301- len + BigInt :: one ( )
302- } else {
303- x + 1
304- }
305- } ) ,
306- start. map ( |x| {
307- if x == -BigInt :: one ( ) {
308- BigInt :: from ( len)
309- } else {
310- x + 1
311- }
312- } ) ,
313- )
314- } else {
315- ( start, stop)
316- } ;
317-
318- let range = saturate_range ( & start, & stop, len) ;
319- let newlen = if range. end > range. start {
320- // overflow is not possible as dividing a positive integer
321- ( ( range. end - range. start - 1 ) / step. abs ( ) )
322- . to_usize ( )
323- . unwrap ( )
324- + 1
325- } else {
291+ if range. start >= range. end {
326292 return Ok ( PyMemoryView {
327293 buffer : zelf. buffer . clone_with_options ( BufferOptions {
328294 len : 0 ,
@@ -340,6 +306,12 @@ impl PyMemoryView {
340306 . into_object ( vm) ) ;
341307 } ;
342308
309+ // overflow is not possible as dividing a positive integer
310+ let newlen = ( ( range. end - range. start - 1 ) / abs_step)
311+ . to_usize ( )
312+ . unwrap ( )
313+ + 1 ;
314+
343315 // newlen will be 0 if step is overflowed
344316 let newstep = newstep. to_isize ( ) . unwrap_or ( -1 ) ;
345317
0 commit comments