diff --git a/newsfragments/5725.changed.md b/newsfragments/5725.changed.md new file mode 100644 index 00000000000..0863a000b82 --- /dev/null +++ b/newsfragments/5725.changed.md @@ -0,0 +1 @@ +Remove redundant internal counters from `BoundSetIterator` and `BoundFrozenSetIterator`. diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index 21d00982718..0e289910987 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -188,18 +188,11 @@ impl<'py> IntoIterator for &Bound<'py, PyFrozenSet> { } /// PyO3 implementation of an iterator for a Python `frozenset` object. -pub struct BoundFrozenSetIterator<'p> { - it: Bound<'p, PyIterator>, - // Remaining elements in the frozenset - remaining: usize, -} +pub struct BoundFrozenSetIterator<'py>(Bound<'py, PyIterator>); impl<'py> BoundFrozenSetIterator<'py> { pub(super) fn new(set: Bound<'py, PyFrozenSet>) -> Self { - Self { - it: PyIterator::from_object(&set).unwrap(), - remaining: set.len(), - } + Self(PyIterator::from_object(&set).expect("frozenset should always be iterable")) } } @@ -208,12 +201,14 @@ impl<'py> Iterator for BoundFrozenSetIterator<'py> { /// Advances the iterator and returns the next value. fn next(&mut self) -> Option { - self.remaining = self.remaining.saturating_sub(1); - self.it.next().map(Result::unwrap) + self.0 + .next() + .map(|result| result.expect("frozenset iteration should be infallible")) } fn size_hint(&self) -> (usize, Option) { - (self.remaining, Some(self.remaining)) + let len = ExactSizeIterator::len(self); + (len, Some(len)) } #[inline] @@ -227,7 +222,7 @@ impl<'py> Iterator for BoundFrozenSetIterator<'py> { impl ExactSizeIterator for BoundFrozenSetIterator<'_> { fn len(&self) -> usize { - self.remaining + self.0.size_hint().0 } } diff --git a/src/types/set.rs b/src/types/set.rs index 69804c18092..7ad5376da39 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -222,19 +222,11 @@ impl<'py> IntoIterator for &Bound<'py, PySet> { } /// PyO3 implementation of an iterator for a Python `set` object. -pub struct BoundSetIterator<'p> { - it: Bound<'p, PyIterator>, - // Remaining elements in the set. This is fine to store because - // Python will error if the set changes size during iteration. - remaining: usize, -} +pub struct BoundSetIterator<'py>(Bound<'py, PyIterator>); impl<'py> BoundSetIterator<'py> { pub(super) fn new(set: Bound<'py, PySet>) -> Self { - Self { - it: PyIterator::from_object(&set).unwrap(), - remaining: set.len(), - } + Self(PyIterator::from_object(&set).expect("set should always be iterable")) } } @@ -243,12 +235,14 @@ impl<'py> Iterator for BoundSetIterator<'py> { /// Advances the iterator and returns the next value. fn next(&mut self) -> Option { - self.remaining = self.remaining.saturating_sub(1); - self.it.next().map(Result::unwrap) + self.0 + .next() + .map(|result| result.expect("set iteration should be infallible")) } fn size_hint(&self) -> (usize, Option) { - (self.remaining, Some(self.remaining)) + let len = ExactSizeIterator::len(self); + (len, Some(len)) } #[inline] @@ -262,7 +256,7 @@ impl<'py> Iterator for BoundSetIterator<'py> { impl ExactSizeIterator for BoundSetIterator<'_> { fn len(&self) -> usize { - self.remaining + self.0.size_hint().0 } }