More generic `new` method for PyList/PyTuple and etc.

This commit is contained in:
messense 2017-05-21 13:55:33 +08:00
parent 3401683eb6
commit 4c802d901b
No known key found for this signature in database
GPG Key ID: BB41A8A2C716CCA9
4 changed files with 34 additions and 44 deletions

View File

@ -445,9 +445,9 @@ pub fn with_extracted_or_default<P: ?Sized, R, F>(py: Python, obj: Option<&PyObj
#[cfg(test)]
mod test {
use python::{Python, PythonObject};
use python::{Python};
use objects::PyTuple;
use conversion::{ToPyObject, ToPyTuple};
use conversion::{ToPyTuple};
#[test]
pub fn test_parse() {
@ -493,7 +493,7 @@ mod test {
assert!(called);
let mut called = false;
let tuple = PyTuple::new(py, &[]);
let tuple = PyTuple::empty(py);
py_argparse!(py, None, &tuple, None, (x: usize = 42, y: &str = "abc") {
assert_eq!(x, 42);
assert_eq!(y, "abc");

View File

@ -17,7 +17,7 @@
// DEALINGS IN THE SOFTWARE.
use err;
use python::{Python, PythonObject, ToPythonPointer};
use python::{Python, PythonObject};
use objects::PyObject;
use ffi::{self, Py_ssize_t};
use conversion::ToPyObject;
@ -29,12 +29,12 @@ pyobject_newtype!(PyList, PyList_Check, PyList_Type);
impl PyList {
/// Construct a new list with the given elements.
pub fn new(py: Python, elements: &[PyObject]) -> PyList {
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> PyList {
unsafe {
let ptr = ffi::PyList_New(elements.len() as Py_ssize_t);
let t = err::result_from_owned_ptr(py, ptr).unwrap().unchecked_cast_into::<PyList>();
for (i, e) in elements.iter().enumerate() {
ffi::PyList_SetItem(ptr, i as Py_ssize_t, e.steal_ptr(py));
ffi::PyList_SetItem(ptr, i as Py_ssize_t, e.to_py_object(py).steal_ptr());
}
t
}
@ -110,15 +110,7 @@ impl <'a, 'p> Iterator for PyListIterator<'a, 'p> {
impl <T> ToPyObject for [T] where T: ToPyObject {
fn to_py_object(&self, py: Python) -> PyObject {
unsafe {
let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
let t = err::cast_from_owned_ptr_or_panic(py, ptr);
for (i, e) in self.iter().enumerate() {
let obj = e.to_py_object(py).into_object();
ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj.steal_ptr());
}
t
}
PyList::new(py, self).into_object()
}
}
@ -143,7 +135,7 @@ impl <T> ToPyObject for Vec<T> where T: ToPyObject {
#[cfg(test)]
mod test {
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast};
use python::{Python, PythonObject};
use conversion::ToPyObject;
use objects::PyList;
@ -151,8 +143,7 @@ mod test {
fn test_len() {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![1,2,3,4];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &[1, 2, 3, 4]);
assert_eq!(4, list.len(py));
}
@ -161,7 +152,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![2, 3, 5, 7];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &v);
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
assert_eq!(3, list.get_item(py, 1).extract::<i32>(py).unwrap());
assert_eq!(5, list.get_item(py, 2).extract::<i32>(py).unwrap());
@ -173,7 +164,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![2, 3, 5, 7];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &v);
let val = 42i32.to_py_object(py).into_object();
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
list.set_item(py, 0, val);
@ -185,7 +176,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![2, 3, 5, 7];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &v);
let val = 42i32.to_py_object(py).into_object();
assert_eq!(4, list.len(py));
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
@ -200,7 +191,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![2, 3, 5, 7];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &v);
let mut idx = 0;
for el in list.iter(py) {
assert_eq!(v[idx], el.extract::<i32>(py).unwrap());
@ -214,7 +205,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let v = vec![2, 3, 5, 7];
let list = PyList::downcast_from(py, v.to_py_object(py)).unwrap();
let list = PyList::new(py, &v);
let v2 = list.into_object().extract::<Vec<i32>>(py).unwrap();
assert_eq!(v, v2);
}

View File

@ -20,7 +20,7 @@ impl PySet {
/// Creates a new set.
///
/// May panic when running out of memory.
pub fn new(py: Python, elements: &[PyObject]) -> PySet {
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> PySet {
let list = elements.to_py_object(py);
unsafe {
err::cast_from_owned_ptr_or_panic(py, ffi::PySet_New(list.as_ptr()))
@ -86,7 +86,7 @@ impl<T> ToPyObject for collections::HashSet<T>
where T: hash::Hash + Eq + ToPyObject
{
fn to_py_object(&self, py: Python) -> PyObject {
let set = PySet::new(py, &[]);
let set = PySet::new::<T>(py, &[]);
for val in self {
set.add(py, val).unwrap();
}
@ -98,7 +98,7 @@ impl<T> ToPyObject for collections::BTreeSet<T>
where T: hash::Hash + Eq + ToPyObject
{
fn to_py_object(&self, py: Python) -> PyObject {
let set = PySet::new(py, &[]);
let set = PySet::new::<T>(py, &[]);
for val in self {
set.add(py, val).unwrap();
}
@ -110,7 +110,7 @@ impl PyFrozenSet {
/// Creates a new frozenset.
///
/// May panic when running out of memory.
pub fn new(py: Python, elements: &[PyObject]) -> PyFrozenSet {
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> PyFrozenSet {
let list = elements.to_py_object(py);
unsafe {
err::cast_from_owned_ptr_or_panic(py, ffi::PyFrozenSet_New(list.as_ptr()))
@ -146,7 +146,7 @@ impl PyFrozenSet {
#[cfg(test)]
mod test {
use std::collections::{HashSet};
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast};
use python::{Python, PythonObjectWithCheckedDowncast};
use conversion::ToPyObject;
use super::{PySet, PyFrozenSet};
@ -155,7 +155,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
assert_eq!(1, set.len(py));
}
@ -176,7 +176,7 @@ mod test {
fn test_set_clear() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
assert_eq!(1, set.len(py));
set.clear(py);
assert_eq!(0, set.len(py));
@ -186,7 +186,7 @@ mod test {
fn test_set_contains() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
assert!(set.contains(py, 1).unwrap());
}
@ -194,7 +194,7 @@ mod test {
fn test_set_discard() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
set.discard(py, 2);
assert_eq!(1, set.len(py));
set.discard(py, 1);
@ -205,8 +205,8 @@ mod test {
fn test_set_add() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[]);
set.add(py, 1).unwrap();
let set = PySet::new(py, &[1, 2]);
set.add(py, 1).unwrap(); // Add a dupliated element
assert!(set.contains(py, 1).unwrap());
}
@ -214,7 +214,7 @@ mod test {
fn test_set_pop() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
let val = set.pop(py);
assert!(val.is_some());
let val2 = set.pop(py);
@ -226,7 +226,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PySet::new(py, &[1.to_py_object(py).into_object()]);
let set = PySet::new(py, &[1]);
for el in set.iter(py).unwrap() {
assert_eq!(1i32, el.unwrap().extract::<i32>(py).unwrap());
}
@ -237,7 +237,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PyFrozenSet::new(py, &[1.to_py_object(py).into_object()]);
let set = PyFrozenSet::new(py, &[1]);
assert_eq!(1, set.len(py));
}
@ -245,7 +245,7 @@ mod test {
fn test_frozenset_contains() {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PyFrozenSet::new(py, &[1.to_py_object(py).into_object()]);
let set = PyFrozenSet::new(py, &[1]);
assert!(set.contains(py, 1).unwrap());
}
@ -254,7 +254,7 @@ mod test {
let gil = Python::acquire_gil();
let py = gil.python();
let set = PyFrozenSet::new(py, &[1.to_py_object(py).into_object()]);
let set = PyFrozenSet::new(py, &[1]);
for el in set.iter(py).unwrap() {
assert_eq!(1i32, el.unwrap().extract::<i32>(py).unwrap());
}

View File

@ -16,7 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use python::{Python, PythonObject, ToPythonPointer, PyClone};
use python::{Python, PythonObject, PyClone};
use err::{self, PyErr, PyResult};
use super::object::PyObject;
use super::exc;
@ -31,13 +31,13 @@ pyobject_newtype!(PyTuple, PyTuple_Check, PyTuple_Type);
impl PyTuple {
/// Construct a new tuple with the given elements.
pub fn new(py: Python, elements: &[PyObject]) -> PyTuple {
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> PyTuple {
unsafe {
let len = elements.len();
let ptr = ffi::PyTuple_New(len as Py_ssize_t);
let t = err::result_cast_from_owned_ptr::<PyTuple>(py, ptr).unwrap();
for (i, e) in elements.iter().enumerate() {
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.steal_ptr(py));
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_py_object(py).steal_ptr());
}
t
}
@ -218,13 +218,12 @@ extract!(obj to NoArgs; py => {
mod test {
use PyTuple;
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast};
use conversion::ToPyObject;
#[test]
fn test_len() {
let gil = Python::acquire_gil();
let py = gil.python();
let tuple = PyTuple::downcast_from(py, (1, 2, 3).to_py_object(py)).unwrap();
let tuple = PyTuple::new(py, &[1, 2, 3]);
assert_eq!(3, tuple.len(py));
assert_eq!((1, 2, 3), tuple.into_object().extract(py).unwrap());
}