Skip to content

Commit 4824183

Browse files
authored
Merge pull request RustPython#3868 from maong0927/arrayiter_reduce
add arrayiter.__reduce__
2 parents d75e388 + 2bf61aa commit 4824183

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

Lib/test/test_array.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,6 @@ def test_pickle_for_empty_array(self):
304304
self.assertEqual(a.x, b.x)
305305
self.assertEqual(type(a), type(b))
306306

307-
# TODO: RUSTPYTHON
308-
@unittest.expectedFailure
309307
def test_iterator_pickle(self):
310308
orig = array.array(self.typecode, self.example)
311309
data = list(orig)

stdlib/src/array.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ mod array {
66
common::{
77
atomic::{self, AtomicUsize},
88
lock::{
9-
PyMappedRwLockReadGuard, PyMappedRwLockWriteGuard, PyRwLock, PyRwLockReadGuard,
10-
PyRwLockWriteGuard,
9+
PyMappedRwLockReadGuard, PyMappedRwLockWriteGuard, PyMutex, PyRwLock,
10+
PyRwLockReadGuard, PyRwLockWriteGuard,
1111
},
1212
str::wchar_t,
1313
},
1414
vm::{
1515
builtins::{
16-
PyByteArray, PyBytes, PyBytesRef, PyDictRef, PyFloat, PyInt, PyIntRef, PyList,
17-
PyListRef, PyStr, PyStrRef, PyTupleRef, PyTypeRef,
16+
PositionIterInternal, PyByteArray, PyBytes, PyBytesRef, PyDictRef, PyFloat, PyInt,
17+
PyIntRef, PyList, PyListRef, PyStr, PyStrRef, PyTupleRef, PyTypeRef,
1818
},
1919
class_or_notimplemented,
2020
convert::{ToPyObject, ToPyResult, TryFromObject},
@@ -1258,9 +1258,8 @@ mod array {
12581258

12591259
impl Iterable for PyArray {
12601260
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
1261-
Ok(PyArrayIterator {
1262-
position: AtomicUsize::new(0),
1263-
array: zelf,
1261+
Ok(PyArrayIter {
1262+
internal: PyMutex::new(PositionIterInternal::new(zelf, 0)),
12641263
}
12651264
.into_pyobject(vm))
12661265
}
@@ -1278,24 +1277,36 @@ mod array {
12781277
#[pyattr]
12791278
#[pyclass(name = "arrayiterator")]
12801279
#[derive(Debug, PyPayload)]
1281-
pub struct PyArrayIterator {
1282-
position: AtomicUsize,
1283-
array: PyArrayRef,
1280+
pub struct PyArrayIter {
1281+
internal: PyMutex<PositionIterInternal<PyArrayRef>>,
12841282
}
12851283

1286-
#[pyimpl(with(IterNext))]
1287-
impl PyArrayIterator {}
1284+
#[pyimpl(with(IterNext), flags(HAS_DICT))]
1285+
impl PyArrayIter {
1286+
#[pymethod(magic)]
1287+
fn setstate(&self, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
1288+
self.internal
1289+
.lock()
1290+
.set_state(state, |obj, pos| pos.min(obj.len()), vm)
1291+
}
12881292

1289-
impl IterNextIterable for PyArrayIterator {}
1290-
impl IterNext for PyArrayIterator {
1293+
#[pymethod(magic)]
1294+
fn reduce(&self, vm: &VirtualMachine) -> PyTupleRef {
1295+
self.internal
1296+
.lock()
1297+
.builtins_iter_reduce(|x| x.clone().into(), vm)
1298+
}
1299+
}
1300+
1301+
impl IterNextIterable for PyArrayIter {}
1302+
impl IterNext for PyArrayIter {
12911303
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
1292-
let pos = zelf.position.fetch_add(1, atomic::Ordering::SeqCst);
1293-
let r = if let Some(item) = zelf.array.read().get(pos, vm) {
1294-
PyIterReturn::Return(item?)
1295-
} else {
1296-
PyIterReturn::StopIteration(None)
1297-
};
1298-
Ok(r)
1304+
zelf.internal.lock().next(|array, pos| {
1305+
Ok(match array.read().get(pos, vm) {
1306+
Some(item) => PyIterReturn::Return(item?),
1307+
None => PyIterReturn::StopIteration(None),
1308+
})
1309+
})
12991310
}
13001311
}
13011312

0 commit comments

Comments
 (0)