Change sig of PyIterProtocol.__next__ method #18

This commit is contained in:
Nikolay Kim 2017-06-08 13:43:24 -07:00
parent 9e08d3eec5
commit 86c20bb139
3 changed files with 48 additions and 17 deletions

View file

@ -264,16 +264,38 @@ fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
// Success // Success
fn get_res_success(ty: &syn::Ty) -> (Tokens, syn::Ty) { fn get_res_success(ty: &syn::Ty) -> (Tokens, syn::Ty) {
let result; let mut result;
let mut succ = match ty { let mut succ;
match ty {
&syn::Ty::Path(_, ref path) => { &syn::Ty::Path(_, ref path) => {
if let Some(segment) = path.segments.last() { if let Some(segment) = path.segments.last() {
match segment.ident.as_ref() { match segment.ident.as_ref() {
// check result type // check for PyResult<T>
"PyResult" => match segment.parameters { "PyResult" => match segment.parameters {
syn::PathParameters::AngleBracketed(ref data) => { syn::PathParameters::AngleBracketed(ref data) => {
result = true; result = true;
data.types[0].clone() succ = data.types[0].clone();
// check for PyResult<Option<T>>
match data.types[0] {
syn::Ty::Path(_, ref path) =>
if let Some(segment) = path.segments.last() {
match segment.ident.as_ref() {
// get T from Option<T>
"Option" => match segment.parameters {
syn::PathParameters::AngleBracketed(ref data) =>
{
result = false;
succ = data.types[0].clone();
},
_ => (),
},
_ => (),
}
},
_ => ()
}
}, },
_ => panic!("fn result type is not supported"), _ => panic!("fn result type is not supported"),
}, },

View file

@ -11,7 +11,7 @@ use err::PyResult;
use python::Python; use python::Python;
use token::ToInstancePtr; use token::ToInstancePtr;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use callback::PyObjectCallbackConverter; use callback::{PyObjectCallbackConverter, IterNextResultConverter};
/// Iterator protocol /// Iterator protocol
@ -32,7 +32,7 @@ pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> { pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
type Success: ::IntoPyObject; type Success: ::IntoPyObject;
type Result: Into<PyResult<Self::Success>>; type Result: Into<PyResult<Option<Self::Success>>>;
} }
@ -91,6 +91,7 @@ impl<T> PyIterNextProtocolImpl for T where T: for<'p> PyIterNextProtocol<'p> + T
{ {
#[inline] #[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> { fn tp_iternext() -> Option<ffi::iternextfunc> {
py_unary_func!(PyIterNextProtocol, T::__next__, T::Success, PyObjectCallbackConverter) py_unary_func!(PyIterNextProtocol, T::__next__,
Option<T::Success>, IterNextResultConverter)
} }
} }

View file

@ -4,7 +4,7 @@
extern crate pyo3; extern crate pyo3;
use pyo3::*; use pyo3::*;
use std::{mem, isize, iter}; use std::{isize, iter};
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -428,27 +428,35 @@ fn len() {
py_expect_exception!(py, inst, "len(inst)", OverflowError); py_expect_exception!(py, inst, "len(inst)", OverflowError);
} }
/*py_class!(class Iterator |py| { #[py::class]
data iter: RefCell<Box<iter::Iterator<Item=i32> + Send>>; struct Iterator{
iter: Box<iter::Iterator<Item=i32> + Send>,
token: PyToken,
}
def __iter__(&self) -> PyResult<Iterator> { #[py::ptr(Iterator)]
Ok(self.clone_ref(py)) struct IteratorPtr(PyPtr);
#[py::proto]
impl PyIterProtocol for Iterator {
fn __iter__(&mut self, py: Python) -> PyResult<IteratorPtr> {
Ok(self.to_inst_ptr())
} }
def __next__(&self) -> PyResult<Option<i32>> { fn __next__(&mut self, py: Python) -> PyResult<Option<i32>> {
Ok(self.iter(py).borrow_mut().next()) Ok(self.iter.next())
} }
}); }
#[test] #[test]
fn iterator() { fn iterator() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
let inst = Iterator::create_instance(py, RefCell::new(Box::new(5..8))).unwrap(); let inst = py.init(|t| Iterator{iter: Box::new(5..8), token: t}).unwrap();
py_assert!(py, inst, "iter(inst) is inst"); py_assert!(py, inst, "iter(inst) is inst");
py_assert!(py, inst, "list(inst) == [5, 6, 7]"); py_assert!(py, inst, "list(inst) == [5, 6, 7]");
}*/ }
#[py::class] #[py::class]
struct StringMethods {token: PyToken} struct StringMethods {token: PyToken}