diff --git a/CHANGELOG.md b/CHANGELOG.md index bd8c315b..e0b3814e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 implementation for `IntoPy for T` where `U: FromPy` 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] * Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692) diff --git a/src/types/set.rs b/src/types/set.rs index c62ef734..e340af9a 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -6,6 +6,8 @@ use crate::ffi; use crate::instance::PyNativeType; use crate::internal_tricks::Unsendable; use crate::object::PyObject; +use crate::objectprotocol::ObjectProtocol; +use crate::types::{PyAny, PyIterator}; use crate::AsPyPointer; use crate::Python; 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 ToPyObject for collections::HashSet where 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)] mod test { use super::{PyFrozenSet, PySet}; @@ -267,9 +287,15 @@ 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()); } + + // intoiterator iteration + for el in set { + assert_eq!(1i32, el.unwrap().extract().unwrap()); + } } #[test] @@ -306,8 +332,15 @@ mod test { let py = gil.python(); let set = PyFrozenSet::new(py, &[1]).unwrap(); + + // objectprotocol iteration for el in set.iter().unwrap() { assert_eq!(1i32, el.unwrap().extract::().unwrap()); } + + // intoiterator iteration + for el in set { + assert_eq!(1i32, el.unwrap().extract::().unwrap()); + } } }