Skip to content

Commit aff07cf

Browse files
authored
Merge pull request RustPython#4390 from garychia/islice-reduce
Implement islice.__reduce__
2 parents 10c9db6 + 49597bc commit aff07cf

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

extra_tests/snippets/stdlib_itertools.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,28 +260,39 @@ def underten(x):
260260
def assert_matches_seq(it, seq):
261261
assert list(it) == list(seq)
262262

263+
def test_islice_pickle(it):
264+
for p in range(pickle.HIGHEST_PROTOCOL + 1):
265+
it == pickle.loads(pickle.dumps(it, p))
266+
263267
i = itertools.islice
264268

265269
it = i([1, 2, 3, 4, 5], 3)
266270
assert_matches_seq(it, [1, 2, 3])
271+
test_islice_pickle(it)
267272

268273
it = i([0.5, 1, 1.5, 2, 2.5, 3, 4, 5], 1, 6, 2)
269274
assert_matches_seq(it, [1, 2, 3])
275+
test_islice_pickle(it)
270276

271277
it = i([1, 2], None)
272278
assert_matches_seq(it, [1, 2])
279+
test_islice_pickle(it)
273280

274281
it = i([1, 2, 3], None, None, None)
275282
assert_matches_seq(it, [1, 2, 3])
283+
test_islice_pickle(it)
276284

277285
it = i([1, 2, 3], 1, None, None)
278286
assert_matches_seq(it, [2, 3])
287+
test_islice_pickle(it)
279288

280289
it = i([1, 2, 3], None, 2, None)
281290
assert_matches_seq(it, [1, 2])
291+
test_islice_pickle(it)
282292

283293
it = i([1, 2, 3], None, None, 3)
284294
assert_matches_seq(it, [1])
295+
test_islice_pickle(it)
285296

286297
# itertools.filterfalse
287298
it = itertools.filterfalse(lambda x: x%2, range(10))

vm/src/stdlib/itertools.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,35 @@ mod decl {
924924
.into_ref_with_type(vm, cls)
925925
.map(Into::into)
926926
}
927+
928+
#[pymethod(magic)]
929+
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
930+
let cls = zelf.class().to_owned();
931+
let itr = zelf.iterable.clone();
932+
let cur = zelf.cur.take();
933+
let next = zelf.next.take();
934+
let step = zelf.step;
935+
match zelf.stop {
936+
Some(stop) => Ok(vm.new_tuple((cls, (itr, next, stop, step), (cur,)))),
937+
_ => Ok(vm.new_tuple((cls, (itr, next, vm.new_pyobj(()), step), (cur,)))),
938+
}
939+
}
940+
941+
#[pymethod(magic)]
942+
fn setstate(zelf: PyRef<Self>, state: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> {
943+
let args = state.as_slice();
944+
if args.len() != 1 {
945+
let msg = format!("function takes exactly 1 argument ({} given)", args.len());
946+
return Err(vm.new_type_error(msg));
947+
}
948+
let cur = &args[0];
949+
if let Ok(cur) = usize::try_from_object(vm, cur.clone()) {
950+
zelf.cur.store(cur);
951+
} else {
952+
return Err(vm.new_type_error(String::from("Argument must be usize.")));
953+
}
954+
Ok(())
955+
}
927956
}
928957

929958
impl IterNextIterable for PyItertoolsIslice {}

0 commit comments

Comments
 (0)