Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more implementations of ExactSizeIterator when iterating built-in Python data structures. #2676

Merged
merged 1 commit into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/2676.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implemented `ExactSizeIterator` for `PyListIterator`, `PyDictIterator`, `PySetIterator` and `PyFrozenSetIterator`
8 changes: 7 additions & 1 deletion src/types/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,17 @@ impl<'py> Iterator for PyDictIterator<'py> {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
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>;
Expand Down
15 changes: 9 additions & 6 deletions src/types/frozenset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ mod impl_ {

/// PyO3 implementation of an iterator for a Python `frozenset` object.
pub struct PyFrozenSetIterator<'py> {
set: &'py PyAny,
set: &'py PyFrozenSet,
pos: ffi::Py_ssize_t,
}

Expand All @@ -143,11 +143,14 @@ mod impl_ {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
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)
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/types/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,14 @@ impl<'a> Iterator for PyListIterator<'a> {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
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)
}
}

Expand Down
15 changes: 9 additions & 6 deletions src/types/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ mod impl_ {

/// PyO3 implementation of an iterator for a Python `set` object.
pub struct PySetIterator<'py> {
set: &'py super::PyAny,
set: &'py super::PySet,
pos: ffi::Py_ssize_t,
used: ffi::Py_ssize_t,
}
Expand Down Expand Up @@ -219,11 +219,14 @@ mod impl_ {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
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)
}
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/types/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,16 +242,14 @@ impl<'a> Iterator for PyTupleIterator<'a> {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(
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)
}
}

Expand Down