diff --git a/newsfragments/2676.added.md b/newsfragments/2676.added.md new file mode 100644 index 00000000000..2dd96585e3a --- /dev/null +++ b/newsfragments/2676.added.md @@ -0,0 +1 @@ +Implemented `ExactSizeIterator` for `PyListIterator`, `PyDictIterator`, `PySetIterator` and `PyFrozenSetIterator` diff --git a/src/types/dict.rs b/src/types/dict.rs index e8fc6f65c02..60dd6433874 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -308,11 +308,17 @@ impl<'py> Iterator for PyDictIterator<'py> { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.len as usize; + let len = self.len(); (len, Some(len)) } } +impl<'py> ExactSizeIterator for PyDictIterator<'py> { + fn len(&self) -> usize { + self.len as usize + } +} + impl<'a> std::iter::IntoIterator for &'a PyDict { type Item = (&'a PyAny, &'a PyAny); type IntoIter = PyDictIterator<'a>; diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index cfe6348fb16..75a4c11ee69 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -117,7 +117,7 @@ mod impl_ { } pub struct PyFrozenSetIterator<'py> { - set: &'py PyAny, + set: &'py PyFrozenSet, pos: ffi::Py_ssize_t, } @@ -141,11 +141,14 @@ mod impl_ { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.set.len().unwrap_or_default(); - ( - len.saturating_sub(self.pos as usize), - Some(len.saturating_sub(self.pos as usize)), - ) + let len = self.len(); + (len, Some(len)) + } + } + + impl<'py> ExactSizeIterator for PyFrozenSetIterator<'py> { + fn len(&self) -> usize { + self.set.len().saturating_sub(self.pos as usize) } } } diff --git a/src/types/list.rs b/src/types/list.rs index 2538833dec7..f8cf3d31cfc 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -321,12 +321,14 @@ impl<'a> Iterator for PyListIterator<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.list.len(); + let len = self.len(); + (len, Some(len)) + } +} - ( - len.saturating_sub(self.index), - Some(len.saturating_sub(self.index)), - ) +impl<'a> ExactSizeIterator for PyListIterator<'a> { + fn len(&self) -> usize { + self.list.len().saturating_sub(self.index) } } diff --git a/src/types/set.rs b/src/types/set.rs index cf97eb484f0..416427ef3fe 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -165,7 +165,7 @@ mod impl_ { mod impl_ { use super::*; pub struct PySetIterator<'py> { - set: &'py super::PyAny, + set: &'py super::PySet, pos: ffi::Py_ssize_t, used: ffi::Py_ssize_t, } @@ -215,11 +215,14 @@ mod impl_ { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.set.len().unwrap_or_default(); - ( - len.saturating_sub(self.pos as usize), - Some(len.saturating_sub(self.pos as usize)), - ) + let len = self.len(); + (len, Some(len)) + } + } + + impl<'py> ExactSizeIterator for PySetIterator<'py> { + fn len(&self) -> usize { + self.set.len().saturating_sub(self.pos as usize) } } } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index b198da72bdd..5f1cb96becd 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -241,16 +241,14 @@ impl<'a> Iterator for PyTupleIterator<'a> { #[inline] fn size_hint(&self) -> (usize, Option) { - ( - self.length.saturating_sub(self.index as usize), - Some(self.length.saturating_sub(self.index as usize)), - ) + let len = self.len(); + (len, Some(len)) } } impl<'a> ExactSizeIterator for PyTupleIterator<'a> { fn len(&self) -> usize { - self.length - self.index + self.length.saturating_sub(self.index) } }