Skip to content

Commit 2868e87

Browse files
authored
Merge pull request RustPython#4235 from dannasman/zip_longest_reduce
Add reduce and setstate for zip_longest
2 parents 2940ef8 + 0706d8e commit 2868e87

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

Lib/test/test_itertools.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,8 +985,6 @@ def test_zip_longest_tuple_reuse(self):
985985
ids = list(map(id, list(zip_longest('abc', 'def'))))
986986
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
987987

988-
# TODO: RUSTPYTHON
989-
@unittest.expectedFailure
990988
def test_zip_longest_pickling(self):
991989
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
992990
self.pickletest(proto, zip_longest("abc", "def"))

vm/src/stdlib/itertools.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ mod decl {
15931593
let iterators = iterators.into_vec();
15941594
PyItertoolsZipLongest {
15951595
iterators,
1596-
fillvalue,
1596+
fillvalue: PyRwLock::new(fillvalue),
15971597
}
15981598
.into_ref_with_type(vm, cls)
15991599
.map(Into::into)
@@ -1605,11 +1605,31 @@ mod decl {
16051605
#[derive(Debug, PyPayload)]
16061606
struct PyItertoolsZipLongest {
16071607
iterators: Vec<PyIter>,
1608-
fillvalue: PyObjectRef,
1608+
fillvalue: PyRwLock<PyObjectRef>,
16091609
}
16101610

16111611
#[pyclass(with(IterNext, Constructor))]
1612-
impl PyItertoolsZipLongest {}
1612+
impl PyItertoolsZipLongest {
1613+
#[pymethod(magic)]
1614+
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
1615+
let args: Vec<PyObjectRef> = zelf
1616+
.iterators
1617+
.iter()
1618+
.map(|i| i.clone().to_pyobject(vm))
1619+
.collect();
1620+
Ok(vm.new_tuple((
1621+
zelf.class().to_owned(),
1622+
vm.new_tuple(args),
1623+
zelf.fillvalue.read().to_owned(),
1624+
)))
1625+
}
1626+
1627+
#[pymethod(magic)]
1628+
fn setstate(zelf: PyRef<Self>, state: PyObjectRef, _vm: &VirtualMachine) -> PyResult<()> {
1629+
*zelf.fillvalue.write() = state;
1630+
Ok(())
1631+
}
1632+
}
16131633
impl IterNextIterable for PyItertoolsZipLongest {}
16141634
impl IterNext for PyItertoolsZipLongest {
16151635
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
@@ -1627,7 +1647,7 @@ mod decl {
16271647
if numactive == 0 {
16281648
return Ok(PyIterReturn::StopIteration(v));
16291649
}
1630-
zelf.fillvalue.clone()
1650+
zelf.fillvalue.read().clone()
16311651
}
16321652
};
16331653
result.push(next_obj);

0 commit comments

Comments
 (0)