temp fix for #71
This commit is contained in:
parent
95915b55dd
commit
5dad22e3db
|
@ -343,11 +343,7 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
|
||||
#[inline]
|
||||
fn iter<'p>(&'p self) -> PyResult<PyIterator<'p>> {
|
||||
unsafe {
|
||||
let ptr = PyObject::from_owned_ptr_or_err(
|
||||
self.py(), ffi::PyObject_GetIter(self.as_ptr()))?;
|
||||
PyIterator::from_object(self.py(), ptr).map_err(|e| e.into())
|
||||
}
|
||||
Ok(PyIterator::from_object(self.py(), self)?)
|
||||
}
|
||||
|
||||
fn get_type(&self) -> &PyType {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use ffi;
|
||||
use objects::PyObjectRef;
|
||||
use python::{Python, ToPyPointer, IntoPyPointer};
|
||||
use python::{Python, ToPyPointer};
|
||||
use instance::PyObjectWithToken;
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
|
||||
|
@ -17,22 +17,22 @@ pub struct PyIterator<'p>(&'p PyObjectRef);
|
|||
|
||||
impl <'p> PyIterator<'p> {
|
||||
/// Constructs a `PyIterator` from a Python iterator object.
|
||||
pub fn from_object<T>(py: Python<'p>, obj: T) -> Result<PyIterator<'p>, PyDowncastError>
|
||||
where T: IntoPyPointer
|
||||
pub fn from_object<T>(py: Python<'p>, obj: &T) -> Result<PyIterator<'p>, PyDowncastError>
|
||||
where T: ToPyPointer
|
||||
{
|
||||
unsafe {
|
||||
let ptr = obj.into_ptr();
|
||||
let ptr = ffi::PyObject_GetIter(obj.as_ptr());
|
||||
|
||||
if ffi::PyIter_Check(ptr) != 0 {
|
||||
Ok(PyIterator(py.cast_from_ptr(ptr)))
|
||||
Ok(PyIterator(py.cast_from_borrowed_ptr(ptr)))
|
||||
} else {
|
||||
ffi::Py_DECREF(ptr);
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <'p> Iterator for PyIterator<'p> {
|
||||
impl<'p> Iterator for PyIterator<'p> {
|
||||
type Item = PyResult<&'p PyObjectRef>;
|
||||
|
||||
/// Retrieves the next item from an iterator.
|
||||
|
@ -58,12 +58,20 @@ impl <'p> Iterator for PyIterator<'p> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Dropping a `PyIterator` instance decrements the reference count on the object by 1.
|
||||
impl<'p> Drop for PyIterator<'p> {
|
||||
|
||||
fn drop(&mut self) {
|
||||
unsafe { ffi::Py_DECREF(self.0.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use instance::AsPyRef;
|
||||
use python::Python;
|
||||
use conversion::{PyTryFrom, ToPyObject};
|
||||
use objects::PyObjectRef;
|
||||
use objects::{PyObjectRef, PyList};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
|
||||
#[test]
|
||||
|
@ -77,4 +85,54 @@ mod tests {
|
|||
assert_eq!(20, it.next().unwrap().unwrap().extract().unwrap());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iter_refcnt() {
|
||||
let obj;
|
||||
let count;
|
||||
{
|
||||
let gil_guard = Python::acquire_gil();
|
||||
let py = gil_guard.python();
|
||||
obj = vec![10, 20].to_object(py);
|
||||
count = obj.get_refcnt();
|
||||
}
|
||||
|
||||
{
|
||||
let gil_guard = Python::acquire_gil();
|
||||
let py = gil_guard.python();
|
||||
let inst = PyObjectRef::try_from(obj.as_ref(py)).unwrap();
|
||||
let mut it = inst.iter().unwrap();
|
||||
|
||||
assert_eq!(10, it.next().unwrap().unwrap().extract().unwrap());
|
||||
}
|
||||
assert_eq!(count, obj.get_refcnt());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iter_item_refcnt() {
|
||||
let obj;
|
||||
let none;
|
||||
let count;
|
||||
{
|
||||
let gil_guard = Python::acquire_gil();
|
||||
let py = gil_guard.python();
|
||||
let l = PyList::empty(py);
|
||||
none = py.None();
|
||||
l.append(10).unwrap();
|
||||
l.append(&none).unwrap();
|
||||
count = none.get_refcnt();
|
||||
obj = l.to_object(py);
|
||||
}
|
||||
|
||||
{
|
||||
let gil_guard = Python::acquire_gil();
|
||||
let py = gil_guard.python();
|
||||
let inst = PyObjectRef::try_from(obj.as_ref(py)).unwrap();
|
||||
let mut it = inst.iter().unwrap();
|
||||
|
||||
assert_eq!(10, it.next().unwrap().unwrap().extract().unwrap());
|
||||
assert!(it.next().unwrap().unwrap().is_none());
|
||||
}
|
||||
assert_eq!(count, none.get_refcnt());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,8 +239,7 @@ fn extract_sequence<'s, T>(obj: &'s PyObjectRef) -> PyResult<Vec<T>> where T: Fr
|
|||
let seq = PySequence::try_from(obj)?;
|
||||
let mut v = Vec::with_capacity(seq.len().unwrap_or(0) as usize);
|
||||
for item in seq.iter()? {
|
||||
let item = try!(item);
|
||||
v.push(item.extract::<T>()?);
|
||||
v.push(item?.extract::<T>()?);
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue