Skip to content

Commit ca1e349

Browse files
authored
support deuqe.index using start, end index (RustPython#2944)
Support deque.index using start, end index
1 parent 1c96338 commit ca1e349

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

Lib/test/test_deque.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ def test_getitem(self):
265265
self.assertRaises(IndexError, d.__getitem__, 0)
266266
self.assertRaises(IndexError, d.__getitem__, -1)
267267

268-
# TODO: RUSTPYTHON
269-
@unittest.expectedFailure
270268
def test_index(self):
271269
for n in 1, 2, 30, 40, 200:
272270

vm/src/stdlib/collections.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod _collections {
1919
use crossbeam_utils::atomic::AtomicCell;
2020
use itertools::Itertools;
2121
use num_traits::ToPrimitive;
22+
use std::cmp::{max, min};
2223
use std::collections::VecDeque;
2324

2425
#[pyattr]
@@ -240,26 +241,44 @@ mod _collections {
240241
Ok(())
241242
}
242243

244+
fn adjust_negative_index(&self, index: isize) -> usize {
245+
if index.is_negative() {
246+
max(index + self.borrow_deque().len() as isize, 0) as usize
247+
} else {
248+
index as usize
249+
}
250+
}
251+
243252
#[pymethod]
244253
fn index(
245254
&self,
246255
obj: PyObjectRef,
247-
start: OptionalArg<usize>,
248-
stop: OptionalArg<usize>,
256+
start: OptionalArg<isize>,
257+
stop: OptionalArg<isize>,
249258
vm: &VirtualMachine,
250259
) -> PyResult<usize> {
251260
let deque = self.borrow_deque().clone();
252-
let start = start.unwrap_or(0);
253261
let start_state = self.state.load();
254-
let stop = stop.unwrap_or_else(|| deque.len());
255-
for (i, elem) in deque.iter().skip(start).take(stop - start).enumerate() {
262+
263+
let start = self.adjust_negative_index(start.unwrap_or(0));
264+
let stop = min(
265+
self.adjust_negative_index(stop.unwrap_or_else(|| deque.len() as isize)),
266+
deque.len(),
267+
);
268+
269+
for (i, elem) in deque
270+
.iter()
271+
.skip(start)
272+
.take(stop.saturating_sub(start))
273+
.enumerate()
274+
{
256275
let is_element = vm.identical_or_equal(elem, &obj)?;
257276

258277
if start_state != self.state.load() {
259278
return Err(vm.new_runtime_error("deque mutated during iteration".to_owned()));
260279
}
261280
if is_element {
262-
return Ok(i);
281+
return Ok(i + start);
263282
}
264283
}
265284
Err(vm.new_value_error(

0 commit comments

Comments
 (0)