Skip to content

Commit c1b5aa7

Browse files
committed
Implement itertools.chain.from_iterable()
1 parent 7be477a commit c1b5aa7

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

tests/snippets/stdlib_itertools.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,36 @@
2121
with assert_raises(TypeError):
2222
next(x)
2323

24+
# empty
25+
with assert_raises(TypeError):
26+
chain.from_iterable()
27+
28+
with assert_raises(TypeError):
29+
chain.from_iterable("abc", "def")
30+
31+
with assert_raises(TypeError):
32+
# iterables are lazily evaluated -- can be constructed but will fail to execute
33+
list(chain.from_iterable([1, 2, 3]))
34+
35+
with assert_raises(TypeError):
36+
list(chain(1))
37+
38+
args = ["abc", "def"]
39+
assert list(chain.from_iterable(args)) == ['a', 'b', 'c', 'd', 'e', 'f']
40+
41+
args = [[], "", b"", ()]
42+
assert list(chain.from_iterable(args)) == []
43+
44+
args = ["ab", "cd", (), 'e']
45+
assert list(chain.from_iterable(args)) == ['a', 'b', 'c', 'd', 'e']
46+
47+
x = chain.from_iterable(["ab", 1])
48+
assert next(x) == 'a'
49+
assert next(x) == 'b'
50+
with assert_raises(TypeError):
51+
next(x)
52+
53+
2454
# itertools.count tests
2555

2656
# default arguments
@@ -117,7 +147,7 @@
117147
with assert_raises(StopIteration):
118148
next(r)
119149

120-
# timees = 0
150+
# times = 0
121151
r = itertools.repeat(1, 0)
122152
with assert_raises(StopIteration):
123153
next(r)

vm/src/stdlib/itertools.rs

+18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::pyobject::{
1919
};
2020
use crate::vm::VirtualMachine;
2121

22+
2223
#[pyclass(name = "chain")]
2324
#[derive(Debug)]
2425
struct PyItertoolsChain {
@@ -73,6 +74,23 @@ impl PyItertoolsChain {
7374
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
7475
zelf
7576
}
77+
78+
#[pyclassmethod(name = "from_iterable")]
79+
fn from_iterable(
80+
cls: PyClassRef,
81+
iterable: PyObjectRef,
82+
vm: &VirtualMachine,
83+
) -> PyResult<PyRef<Self>> {
84+
85+
let it = get_iter(vm, &iterable)?;
86+
let iterables = get_all(vm, &it)?;
87+
88+
PyItertoolsChain {
89+
iterables: iterables,
90+
cur: RefCell::new((0, None)),
91+
}
92+
.into_ref_with_type(vm, cls)
93+
}
7694
}
7795

7896
#[pyclass(name = "compress")]

0 commit comments

Comments
 (0)