From 026caeda684148191e65a4f0d8017193e9eb7a98 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Wed, 8 Jan 2020 23:15:53 +0900 Subject: [PATCH 1/3] Implement iter for PySet and PyFrozenSet --- src/types/dict.rs | 6 +++--- src/types/set.rs | 34 +++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/types/dict.rs b/src/types/dict.rs index 287334cfa42..418819d203d 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -150,9 +150,9 @@ impl PyDict { } } - /// Returns a iterator of (key, value) pairs in this dictionary - /// Note that it's unsafe to use when the dictionary might be changed - /// by other python code. + /// Returns a iterator of (key, value) pairs in this dictionary. + /// + /// Note that it's unsafe to use when the dictionary might be changed by other code. pub fn iter(&self) -> PyDictIterator { let py = self.py(); PyDictIterator { diff --git a/src/types/set.rs b/src/types/set.rs index bb75b9e557f..e1257b8b806 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -95,6 +95,14 @@ impl PySet { pub fn pop(&self) -> Option { unsafe { PyObject::from_owned_ptr_or_opt(self.py(), ffi::PySet_Pop(self.as_ptr())) } } + + /// Returns an iterator of values in this set. + /// + /// Note that it can be unsafe to use when the set might be changed by other code. + #[cfg(not(Py_LIMITED_API))] + pub fn iter(&self) -> PySetIterator { + self.into_iter() + } } #[cfg(not(Py_LIMITED_API))] @@ -204,7 +212,16 @@ impl PyFrozenSet { } }) } + + /// Returns an iterator of values in this frozen set. + /// + /// Note that it can be unsafe to use when the set might be changed by other code. + #[cfg(not(Py_LIMITED_API))] + pub fn iter(&self) -> PySetIterator { + self.into_iter() + } } + #[cfg(not(Py_LIMITED_API))] impl<'a> std::iter::IntoIterator for &'a PyFrozenSet { type Item = &'a PyAny; @@ -222,9 +239,7 @@ impl<'a> std::iter::IntoIterator for &'a PyFrozenSet { mod test { use super::{PyFrozenSet, PySet}; use crate::instance::AsPyRef; - use crate::objectprotocol::ObjectProtocol; - use crate::Python; - use crate::{PyTryFrom, ToPyObject}; + use crate::{ObjectProtocol, PyTryFrom, Python, ToPyObject}; use std::collections::HashSet; #[test] @@ -317,9 +332,10 @@ mod test { let py = gil.python(); let set = PySet::new(py, &[1]).unwrap(); - // objectprotocol iteration - for el in set.iter().unwrap() { - assert_eq!(1i32, el.unwrap().extract::().unwrap()); + + // iter method + for el in set.iter() { + assert_eq!(1i32, el.extract().unwrap()); } // intoiterator iteration @@ -363,9 +379,9 @@ mod test { let set = PyFrozenSet::new(py, &[1]).unwrap(); - // objectprotocol iteration - for el in set.iter().unwrap() { - assert_eq!(1i32, el.unwrap().extract::().unwrap()); + // iter method + for el in set.iter() { + assert_eq!(1i32, el.extract::().unwrap()); } // intoiterator iteration From 7b502821ce5f58b471781de09a8a1ae1a0635e52 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Wed, 8 Jan 2020 23:43:26 +0900 Subject: [PATCH 2/3] Use &PyAny instead of PyObject in PyDictIterator --- src/types/dict.rs | 9 +++------ src/types/set.rs | 10 +++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/types/dict.rs b/src/types/dict.rs index 418819d203d..74bbd0c412f 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -154,19 +154,16 @@ impl PyDict { /// /// Note that it's unsafe to use when the dictionary might be changed by other code. pub fn iter(&self) -> PyDictIterator { - let py = self.py(); PyDictIterator { - dict: self.to_object(py), + dict: self.as_ref(), pos: 0, - py, } } } pub struct PyDictIterator<'py> { - dict: PyObject, + dict: &'py PyAny, pos: isize, - py: Python<'py>, } impl<'py> Iterator for PyDictIterator<'py> { @@ -178,7 +175,7 @@ impl<'py> Iterator for PyDictIterator<'py> { let mut key: *mut ffi::PyObject = std::ptr::null_mut(); let mut value: *mut ffi::PyObject = std::ptr::null_mut(); if ffi::PyDict_Next(self.dict.as_ptr(), &mut self.pos, &mut key, &mut value) != 0 { - let py = self.py; + let py = self.dict.py(); Some((py.from_borrowed_ptr(key), py.from_borrowed_ptr(value))) } else { None diff --git a/src/types/set.rs b/src/types/set.rs index e1257b8b806..23c43f0be57 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -101,7 +101,10 @@ impl PySet { /// Note that it can be unsafe to use when the set might be changed by other code. #[cfg(not(Py_LIMITED_API))] pub fn iter(&self) -> PySetIterator { - self.into_iter() + PySetIterator { + set: self.as_ref(), + pos: 0, + } } } @@ -135,10 +138,7 @@ impl<'a> std::iter::IntoIterator for &'a PySet { type IntoIter = PySetIterator<'a>; fn into_iter(self) -> Self::IntoIter { - PySetIterator { - set: self.as_ref(), - pos: 0, - } + self.iter() } } From ea9824a982de1fa709b20b789f0a13e0b72a0674 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Wed, 8 Jan 2020 23:44:16 +0900 Subject: [PATCH 3/3] Fix document for PyList::iter --- src/types/list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/list.rs b/src/types/list.rs index 9392482d2cd..484ba5d0ae4 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -113,7 +113,7 @@ impl PyList { }) } - /// Returns an iterator over the tuple items. + /// Returns an iterator over this list items. pub fn iter(&self) -> PyListIterator { PyListIterator { list: self,