1
- use super :: { PositionIterInternal , PyGenericAlias , PyTupleRef , PyType , PyTypeRef } ;
1
+ use super :: { PositionIterInternal , PyGenericAlias , PyIntRef , PyTupleRef , PyType , PyTypeRef } ;
2
2
use crate :: common:: lock:: {
3
3
PyMappedRwLockReadGuard , PyMutex , PyRwLock , PyRwLockReadGuard , PyRwLockWriteGuard ,
4
4
} ;
@@ -10,7 +10,7 @@ use crate::{
10
10
protocol:: { PyIterReturn , PyMappingMethods , PySequence , PySequenceMethods } ,
11
11
recursion:: ReprGuard ,
12
12
sequence:: { MutObjectSequenceOp , SequenceExt , SequenceMutExt } ,
13
- sliceable:: { saturate_index , SequenceIndex , SliceableSequenceMutOp , SliceableSequenceOp } ,
13
+ sliceable:: { SequenceIndex , SliceableSequenceMutOp , SliceableSequenceOp } ,
14
14
types:: {
15
15
AsMapping , AsSequence , Comparable , Constructor , Hashable , Initializer , IterNext ,
16
16
IterNextIterable , Iterable , PyComparisonOp , Unconstructible , Unhashable ,
@@ -19,6 +19,7 @@ use crate::{
19
19
vm:: VirtualMachine ,
20
20
AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult ,
21
21
} ;
22
+ use num_traits:: Signed ;
22
23
use std:: { fmt, ops:: DerefMut } ;
23
24
24
25
/// Built-in mutable sequence.
@@ -271,15 +272,61 @@ impl PyList {
271
272
fn index (
272
273
& self ,
273
274
needle : PyObjectRef ,
274
- start : OptionalArg < isize > ,
275
- stop : OptionalArg < isize > ,
275
+ start : OptionalArg < PyObjectRef > ,
276
+ stop : OptionalArg < PyObjectRef > ,
276
277
vm : & VirtualMachine ,
277
278
) -> PyResult < usize > {
278
279
let len = self . len ( ) ;
279
- let start = start. map ( |i| saturate_index ( i, len) ) . unwrap_or ( 0 ) ;
280
- let stop = stop
281
- . map ( |i| saturate_index ( i, len) )
282
- . unwrap_or ( isize:: MAX as usize ) ;
280
+ let start: OptionalArg < PyIntRef > = match start {
281
+ OptionalArg :: Missing => OptionalArg :: Missing ,
282
+ OptionalArg :: Present ( obj) => OptionalArg :: Present ( obj. try_into_value ( vm) ?) ,
283
+ } ;
284
+ let stop: OptionalArg < PyIntRef > = match stop {
285
+ OptionalArg :: Missing => OptionalArg :: Missing ,
286
+ OptionalArg :: Present ( obj) => OptionalArg :: Present ( obj. try_into_value ( vm) ?) ,
287
+ } ;
288
+ let start: usize = match start {
289
+ OptionalArg :: Missing => 0 ,
290
+ OptionalArg :: Present ( obj) => {
291
+ let bigint = obj. as_bigint ( ) ;
292
+ if bigint. is_negative ( ) {
293
+ let idx: Result < usize , _ > = bigint. abs ( ) . try_into ( ) ;
294
+ match idx {
295
+ Ok ( abs) => {
296
+ if abs >= len {
297
+ 0
298
+ } else {
299
+ len - abs
300
+ }
301
+ }
302
+ Err ( _) => 0 ,
303
+ }
304
+ } else {
305
+ bigint. try_into ( ) . unwrap_or ( len)
306
+ }
307
+ }
308
+ } ;
309
+ let stop: usize = match stop {
310
+ OptionalArg :: Missing => len,
311
+ OptionalArg :: Present ( obj) => {
312
+ let bigint = obj. as_bigint ( ) ;
313
+ if bigint. is_negative ( ) {
314
+ let idx: Result < usize , _ > = bigint. abs ( ) . try_into ( ) ;
315
+ match idx {
316
+ Ok ( abs) => {
317
+ if abs >= len {
318
+ 0
319
+ } else {
320
+ len - abs
321
+ }
322
+ }
323
+ Err ( _) => 0 ,
324
+ }
325
+ } else {
326
+ bigint. try_into ( ) . unwrap_or ( len)
327
+ }
328
+ }
329
+ } ;
283
330
let index = self . mut_index_range ( vm, & needle, start..stop) ?;
284
331
if let Some ( index) = index. into ( ) {
285
332
Ok ( index)
0 commit comments