1- use super :: { PositionIterInternal , PyGenericAlias , PyTupleRef , PyType , PyTypeRef } ;
1+ use super :: { PositionIterInternal , PyGenericAlias , PyIntRef , PyTupleRef , PyType , PyTypeRef } ;
22use crate :: common:: lock:: {
33 PyMappedRwLockReadGuard , PyMutex , PyRwLock , PyRwLockReadGuard , PyRwLockWriteGuard ,
44} ;
@@ -10,7 +10,7 @@ use crate::{
1010 protocol:: { PyIterReturn , PyMappingMethods , PySequence , PySequenceMethods } ,
1111 recursion:: ReprGuard ,
1212 sequence:: { MutObjectSequenceOp , SequenceExt , SequenceMutExt } ,
13- sliceable:: { saturate_index , SequenceIndex , SliceableSequenceMutOp , SliceableSequenceOp } ,
13+ sliceable:: { SequenceIndex , SliceableSequenceMutOp , SliceableSequenceOp } ,
1414 types:: {
1515 AsMapping , AsSequence , Comparable , Constructor , Hashable , Initializer , IterNext ,
1616 IterNextIterable , Iterable , PyComparisonOp , Unconstructible , Unhashable ,
@@ -19,6 +19,7 @@ use crate::{
1919 vm:: VirtualMachine ,
2020 AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult ,
2121} ;
22+ use num_traits:: Signed ;
2223use std:: { fmt, ops:: DerefMut } ;
2324
2425/// Built-in mutable sequence.
@@ -271,15 +272,61 @@ impl PyList {
271272 fn index (
272273 & self ,
273274 needle : PyObjectRef ,
274- start : OptionalArg < isize > ,
275- stop : OptionalArg < isize > ,
275+ start : OptionalArg < PyObjectRef > ,
276+ stop : OptionalArg < PyObjectRef > ,
276277 vm : & VirtualMachine ,
277278 ) -> PyResult < usize > {
278279 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+ } ;
283330 let index = self . mut_index_range ( vm, & needle, start..stop) ?;
284331 if let Some ( index) = index. into ( ) {
285332 Ok ( index)
0 commit comments