Skip to content

Commit 83e2490

Browse files
committed
Saturate on usize.
1 parent 7848e06 commit 83e2490

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

Lib/test/list_tests.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,6 @@ def __eq__(self, other):
363363
# verify that original order and values are retained.
364364
self.assertIs(x, y)
365365

366-
# TODO: RUSTPYTHON
367-
@unittest.expectedFailure
368366
def test_index(self):
369367
super().test_index()
370368
a = self.type2test([-2, -1, 0, 0, 1, 2])

vm/src/builtins/list.rs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{PositionIterInternal, PyGenericAlias, PyTupleRef, PyType, PyTypeRef};
1+
use super::{PositionIterInternal, PyGenericAlias, PyIntRef, PyTupleRef, PyType, PyTypeRef};
22
use 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;
2223
use 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

Comments
 (0)