@@ -344,7 +344,79 @@ macro_rules! def_array_enum {
344
344
}
345
345
346
346
fn delitem_by_slice( & mut self , slice: PySliceRef , vm: & VirtualMachine ) -> PyResult <( ) > {
347
- Err ( vm. new_not_implemented_error( "FIX NOW" . to_owned( ) ) )
347
+ let start = slice. start_index( vm) ?;
348
+ let stop = slice. stop_index( vm) ?;
349
+ let step = slice. step_index( vm) ?. unwrap_or_else( BigInt :: one) ;
350
+
351
+ if step. is_zero( ) {
352
+ return Err ( vm. new_value_error( "slice step cannot be zero" . to_owned( ) ) ) ;
353
+ }
354
+
355
+ match self {
356
+ $( ArrayContentType :: $n( elements) => {
357
+ if step == BigInt :: one( ) {
358
+ let range = get_slice_range( & start, & stop, elements. len( ) ) ;
359
+ if range. start < range. end {
360
+ elements. drain( range) ;
361
+ }
362
+ return Ok ( ( ) ) ;
363
+ }
364
+
365
+ let ( start, stop, step, is_negative_step) = if step. is_negative( ) {
366
+ (
367
+ stop. map( |x| if x == -BigInt :: one( ) {
368
+ elements. len( ) + BigInt :: one( )
369
+ } else {
370
+ x + 1
371
+ } ) ,
372
+ start. map( |x| if x == -BigInt :: one( ) {
373
+ BigInt :: from( elements. len( ) )
374
+ } else {
375
+ x + 1
376
+ } ) ,
377
+ -step,
378
+ true
379
+ )
380
+ } else {
381
+ ( start, stop, step, false )
382
+ } ;
383
+
384
+ let range = get_slice_range( & start, & stop, elements. len( ) ) ;
385
+ if range. start >= range. end {
386
+ return Ok ( ( ) ) ;
387
+ }
388
+
389
+ // step is not negative here
390
+ if let Some ( step) = step. to_usize( ) {
391
+ let mut indexes = if is_negative_step {
392
+ itertools:: Either :: Left ( range. clone( ) . rev( ) . step_by( step) . rev( ) ) . peekable( )
393
+ } else {
394
+ itertools:: Either :: Right ( range. clone( ) . step_by( step) ) . peekable( )
395
+ } ;
396
+
397
+ let mut deleted = 0 ;
398
+
399
+ // passing whole range, swap or overlap
400
+ for i in range. clone( ) {
401
+ if indexes. peek( ) == Some ( & i) {
402
+ indexes. next( ) ;
403
+ deleted += 1 ;
404
+ } else {
405
+ elements. swap( i - deleted, i) ;
406
+ }
407
+ }
408
+ // then drain (the values to delete should now be contiguous at the end of the range)
409
+ elements. drain( ( range. end - deleted) ..range. end) ;
410
+ } else {
411
+ // edge case, step is too big for usize
412
+ // same behaviour as CPython
413
+ elements. remove(
414
+ if is_negative_step { range. end -1 } else { range. start }
415
+ ) ;
416
+ }
417
+ Ok ( ( ) )
418
+ } ) *
419
+ }
348
420
}
349
421
350
422
fn repr( & self , _vm: & VirtualMachine ) -> PyResult <String > {
@@ -596,7 +668,7 @@ impl PyArray {
596
668
fn delitem ( & self , needle : Either < isize , PySliceRef > , vm : & VirtualMachine ) -> PyResult < ( ) > {
597
669
match needle {
598
670
Either :: A ( i) => self . borrow_value_mut ( ) . delitem_by_idx ( i, vm) ,
599
- Either :: B ( slice) => self . borrow_value_mut ( ) . delitem_by_slice ( slice, vm)
671
+ Either :: B ( slice) => self . borrow_value_mut ( ) . delitem_by_slice ( slice, vm) ,
600
672
}
601
673
}
602
674
0 commit comments