mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
add __new__ method to deque iterator and reverse iterator (#2987)
* add __new__ method to deque iterator and reverse iterator
This commit is contained in:
1 parent
2aa58cc551
commit
e4953efac1
3 files changed
+136
-8
No files matched your search
@@ -646,8 +646,6 @@ class TestBasic(unittest.TestCase):
|
||||
self.assertEqual(id(e[-1]), id(e))
|
||||
self.assertEqual(e.maxlen, d.maxlen)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_iterator_pickle(self):
|
||||
orig = deque(range(200))
|
||||
data = [i*1.01 for i in orig]
|
||||
@@ -729,8 +727,6 @@ class TestBasic(unittest.TestCase):
|
||||
for s in ('abcd', range(2000)):
|
||||
self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_reversed_new(self):
|
||||
klass = type(reversed(deque()))
|
||||
for s in ('abcd', range(2000)):
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
from collections import deque
|
||||
|
||||
|
||||
def test_deque_iterator__new__():
|
||||
klass = type(iter(deque()))
|
||||
s = 'abcd'
|
||||
d = klass(deque(s))
|
||||
assert (list(d) == list(s))
|
||||
|
||||
|
||||
test_deque_iterator__new__()
|
||||
|
||||
|
||||
def test_deque_iterator__new__positional_index():
|
||||
klass = type(iter(deque()))
|
||||
|
||||
# index between 0 and len
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(len(s)):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list(s)[i:])
|
||||
|
||||
# negative index
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(-1000, 0):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list(s))
|
||||
|
||||
# index ge len
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(len(s), 4000):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list())
|
||||
|
||||
|
||||
test_deque_iterator__new__positional_index()
|
||||
|
||||
|
||||
def test_deque_iterator__new__not_using_keyword_index():
|
||||
klass = type(iter(deque()))
|
||||
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(-1000, 4000):
|
||||
d = klass(deque(s), index=i)
|
||||
assert (list(d) == list(s))
|
||||
|
||||
|
||||
test_deque_iterator__new__not_using_keyword_index()
|
||||
|
||||
|
||||
def test_deque_reverse_iterator__new__positional_index():
|
||||
klass = type(reversed(deque()))
|
||||
|
||||
# index between 0 and len
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(len(s)):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list(reversed(s))[i:])
|
||||
|
||||
# negative index
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(-1000, 0):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list(reversed(s)))
|
||||
|
||||
# index ge len
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(len(s), 4000):
|
||||
d = klass(deque(s), i)
|
||||
assert (list(d) == list())
|
||||
|
||||
|
||||
test_deque_reverse_iterator__new__positional_index()
|
||||
|
||||
|
||||
def test_deque_reverse_iterator__new__not_using_keyword_index():
|
||||
klass = type(reversed(deque()))
|
||||
|
||||
for s in ('abcd', range(2000)):
|
||||
for i in range(-1000, 4000):
|
||||
d = klass(deque(s), index=i)
|
||||
assert (list(d) == list(reversed(s)))
|
||||
|
||||
|
||||
test_deque_reverse_iterator__new__not_using_keyword_index()
|
||||
@@ -3,7 +3,7 @@ pub(crate) use _collections::make_module;
|
||||
#[pymodule]
|
||||
mod _collections {
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::function::{FuncArgs, KwArgs, OptionalArg};
|
||||
use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable};
|
||||
use crate::vm::ReprGuard;
|
||||
use crate::VirtualMachine;
|
||||
@@ -361,15 +361,14 @@ mod _collections {
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reversed(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
|
||||
fn reversed(zelf: PyRef<Self>) -> PyResult<PyReverseDequeIterator> {
|
||||
let length = zelf.len();
|
||||
Ok(PyReverseDequeIterator {
|
||||
position: AtomicCell::new(length),
|
||||
status: AtomicCell::new(if length > 0 { Active } else { Exhausted }),
|
||||
length,
|
||||
deque: zelf,
|
||||
}
|
||||
.into_object(vm))
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -581,6 +580,15 @@ mod _collections {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
struct DequeIterArgs {
|
||||
#[pyarg(positional)]
|
||||
deque: PyDequeRef,
|
||||
|
||||
#[pyarg(positional, optional)]
|
||||
index: OptionalArg<isize>,
|
||||
}
|
||||
|
||||
#[pyimpl(with(PyIter))]
|
||||
impl PyDequeIterator {
|
||||
pub(crate) fn new(deque: PyDequeRef) -> Self {
|
||||
@@ -592,6 +600,26 @@ mod _collections {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
fn tp_new(
|
||||
cls: PyTypeRef,
|
||||
DequeIterArgs { deque, index }: DequeIterArgs,
|
||||
_kwargs: KwArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
let len = deque.len();
|
||||
let iter = PyDequeIterator::new(deque);
|
||||
if let OptionalArg::Present(index) = index {
|
||||
let index = max(index, 0) as usize;
|
||||
iter.position.store(min(index, len));
|
||||
|
||||
if len.le(&index) {
|
||||
iter.status.store(Exhausted);
|
||||
}
|
||||
}
|
||||
iter.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn length_hint(&self) -> usize {
|
||||
match self.status.load() {
|
||||
@@ -663,6 +691,25 @@ mod _collections {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
fn tp_new(
|
||||
cls: PyTypeRef,
|
||||
DequeIterArgs { deque, index }: DequeIterArgs,
|
||||
_kwargs: KwArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
let len = deque.len();
|
||||
let iter = PyDeque::reversed(deque)?;
|
||||
if let OptionalArg::Present(index) = index {
|
||||
let index = max(index, 0) as usize;
|
||||
if len.le(&index) {
|
||||
iter.status.store(Exhausted);
|
||||
}
|
||||
iter.position.store(len.saturating_sub(index));
|
||||
}
|
||||
iter.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(
|
||||
zelf: PyRef<Self>,
|
||||
|
||||
Reference in new issue
Block a user