Skip to content

Commit a48d74c

Browse files
committed
Fix #19: allow extracting a Vec from anything implementing the sequence protocol, not just from list.
1 parent fbe1a07 commit a48d74c

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

src/objects/list.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -143,22 +143,6 @@ impl <T> ToPyObject for Vec<T> where T: ToPyObject {
143143
}
144144
}
145145

146-
impl <'source, T> FromPyObject<'source> for Vec<T>
147-
where for<'a> T: FromPyObject<'a>
148-
{
149-
fn extract(py: Python, obj: &'source PyObject) -> PyResult<Self> {
150-
let list = try!(obj.cast_as::<PyList>(py));
151-
let len = list.len(py);
152-
let mut v = Vec::with_capacity(len);
153-
for i in 0 .. len {
154-
let item = list.get_item(py, i);
155-
v.push(try!(T::extract(py, &item)));
156-
item.release_ref(py);
157-
}
158-
Ok(v)
159-
}
160-
}
161-
162146
#[cfg(test)]
163147
mod test {
164148
use python::{Python, PythonObject};

src/objects/sequence.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
use std::mem;
2020
use ffi;
21-
use python::{Python, PythonObject, ToPythonPointer, PyClone};
22-
use conversion::ToPyObject;
21+
use python::{Python, PythonObject, ToPythonPointer, PyClone, PyDrop};
22+
use conversion::{FromPyObject, ToPyObject};
2323
use objects::{PyObject, PyList, PyTuple, PyIterator};
2424
use ffi::Py_ssize_t;
2525
use err;
@@ -208,6 +208,21 @@ impl PySequence {
208208
}
209209
}
210210

211+
impl <'source, T> FromPyObject<'source> for Vec<T>
212+
where for<'a> T: FromPyObject<'a>
213+
{
214+
fn extract(py: Python, obj: &'source PyObject) -> PyResult<Self> {
215+
let seq = try!(obj.cast_as::<PySequence>(py));
216+
let mut v = Vec::new();
217+
for item in try!(seq.iter(py)) {
218+
let item = try!(item);
219+
v.push(try!(T::extract(py, &item)));
220+
item.release_ref(py);
221+
}
222+
Ok(v)
223+
}
224+
}
225+
211226
#[cfg(test)]
212227
mod test {
213228
use std;
@@ -386,8 +401,8 @@ mod test {
386401
let concat_seq = seq.concat(py, &seq).unwrap().cast_into::<PySequence>(py).unwrap();
387402
assert_eq!(12, concat_seq.len(py).unwrap());
388403
/*let concat_v = "stringstring".to_owned();
389-
for (el, cc) in seq.into_iter(py).zip(concat_v.chars()) {
390-
assert_eq!(cc, el.extract::<char>(py).unwrap()); TODO: extract::<char>() is not implemented
404+
for (el, cc) in seq.iter(py).unwrap().zip(concat_v.chars()) {
405+
assert_eq!(cc, el.unwrap().extract::<char>(py).unwrap()); //TODO: extract::<char>() is not implemented
391406
}*/
392407
}
393408

@@ -440,4 +455,20 @@ mod test {
440455
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
441456
assert!(seq.tuple(py).is_ok());
442457
}
458+
459+
#[test]
460+
fn test_extract_tuple_to_vec() {
461+
let gil = Python::acquire_gil();
462+
let py = gil.python();
463+
let v: Vec<i32> = py.eval("(1, 2)", None, None).unwrap().extract(py).unwrap();
464+
assert!(v == [1, 2]);
465+
}
466+
467+
#[test]
468+
fn test_extract_range_to_vec() {
469+
let gil = Python::acquire_gil();
470+
let py = gil.python();
471+
let v: Vec<i32> = py.eval("range(1, 5)", None, None).unwrap().extract(py).unwrap();
472+
assert!(v == [1, 2, 3, 4]);
473+
}
443474
}

0 commit comments

Comments
 (0)