Implement IntoIterator for PySet and PyFrozenSet

This commit is contained in:
David Hewitt 2020-01-08 00:05:03 +00:00
parent 18440d7af5
commit ec79285fe4
2 changed files with 37 additions and 0 deletions

View File

@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* The blanket implementations for `FromPyObject` for `&T` and `&mut T` are no longer specializable. Implement `PyTryFrom` for your type to control the behavior of `FromPyObject::extract()` for your types. * The blanket implementations for `FromPyObject` for `&T` and `&mut T` are no longer specializable. Implement `PyTryFrom` for your type to control the behavior of `FromPyObject::extract()` for your types.
* The implementation for `IntoPy<U> for T` where `U: FromPy<T>` is no longer specializable. Control the behavior of this via the implementation of `FromPy`. * The implementation for `IntoPy<U> for T` where `U: FromPy<T>` is no longer specializable. Control the behavior of this via the implementation of `FromPy`.
### Added
* Implemented `IntoIterator` for `PySet` and `PyFrozenSet`. [#716](https://github.com/PyO3/pyo3/pull/716)
## [0.8.5] ## [0.8.5]
* Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692) * Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)

View File

@ -6,6 +6,8 @@ use crate::ffi;
use crate::instance::PyNativeType; use crate::instance::PyNativeType;
use crate::internal_tricks::Unsendable; use crate::internal_tricks::Unsendable;
use crate::object::PyObject; use crate::object::PyObject;
use crate::objectprotocol::ObjectProtocol;
use crate::types::{PyAny, PyIterator};
use crate::AsPyPointer; use crate::AsPyPointer;
use crate::Python; use crate::Python;
use crate::{ToBorrowedObject, ToPyObject}; use crate::{ToBorrowedObject, ToPyObject};
@ -96,6 +98,15 @@ impl PySet {
} }
} }
impl<'a> std::iter::IntoIterator for &'a PySet {
type Item = PyResult<&'a PyAny>;
type IntoIter = PyIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter().expect("Failed to get set iterator")
}
}
impl<T> ToPyObject for collections::HashSet<T> impl<T> ToPyObject for collections::HashSet<T>
where where
T: hash::Hash + Eq + ToPyObject, T: hash::Hash + Eq + ToPyObject,
@ -168,6 +179,15 @@ impl PyFrozenSet {
} }
} }
impl<'a> std::iter::IntoIterator for &'a PyFrozenSet {
type Item = PyResult<&'a PyAny>;
type IntoIter = PyIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter().expect("Failed to get frozen set iterator")
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::{PyFrozenSet, PySet}; use super::{PyFrozenSet, PySet};
@ -267,9 +287,15 @@ mod test {
let py = gil.python(); let py = gil.python();
let set = PySet::new(py, &[1]).unwrap(); let set = PySet::new(py, &[1]).unwrap();
// objectprotocol iteration
for el in set.iter().unwrap() { for el in set.iter().unwrap() {
assert_eq!(1i32, el.unwrap().extract::<i32>().unwrap()); assert_eq!(1i32, el.unwrap().extract::<i32>().unwrap());
} }
// intoiterator iteration
for el in set {
assert_eq!(1i32, el.unwrap().extract().unwrap());
}
} }
#[test] #[test]
@ -306,8 +332,15 @@ mod test {
let py = gil.python(); let py = gil.python();
let set = PyFrozenSet::new(py, &[1]).unwrap(); let set = PyFrozenSet::new(py, &[1]).unwrap();
// objectprotocol iteration
for el in set.iter().unwrap() { for el in set.iter().unwrap() {
assert_eq!(1i32, el.unwrap().extract::<i32>().unwrap()); assert_eq!(1i32, el.unwrap().extract::<i32>().unwrap());
} }
// intoiterator iteration
for el in set {
assert_eq!(1i32, el.unwrap().extract::<i32>().unwrap());
}
} }
} }