Skip to content

Commit 125af9b

Browse files
authored
Merge pull request #2676 from PyO3/exact-iter
Add more implementations of ExactSizeIterator when iterating built-in Python data structures.
2 parents 61fd70c + cd361dc commit 125af9b

File tree

6 files changed

+36
-23
lines changed

6 files changed

+36
-23
lines changed

newsfragments/2676.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implemented `ExactSizeIterator` for `PyListIterator`, `PyDictIterator`, `PySetIterator` and `PyFrozenSetIterator`

src/types/dict.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,17 @@ impl<'py> Iterator for PyDictIterator<'py> {
310310

311311
#[inline]
312312
fn size_hint(&self) -> (usize, Option<usize>) {
313-
let len = self.len as usize;
313+
let len = self.len();
314314
(len, Some(len))
315315
}
316316
}
317317

318+
impl<'py> ExactSizeIterator for PyDictIterator<'py> {
319+
fn len(&self) -> usize {
320+
self.len as usize
321+
}
322+
}
323+
318324
impl<'a> std::iter::IntoIterator for &'a PyDict {
319325
type Item = (&'a PyAny, &'a PyAny);
320326
type IntoIter = PyDictIterator<'a>;

src/types/frozenset.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ mod impl_ {
119119

120120
/// PyO3 implementation of an iterator for a Python `frozenset` object.
121121
pub struct PyFrozenSetIterator<'py> {
122-
set: &'py PyAny,
122+
set: &'py PyFrozenSet,
123123
pos: ffi::Py_ssize_t,
124124
}
125125

@@ -143,11 +143,14 @@ mod impl_ {
143143

144144
#[inline]
145145
fn size_hint(&self) -> (usize, Option<usize>) {
146-
let len = self.set.len().unwrap_or_default();
147-
(
148-
len.saturating_sub(self.pos as usize),
149-
Some(len.saturating_sub(self.pos as usize)),
150-
)
146+
let len = self.len();
147+
(len, Some(len))
148+
}
149+
}
150+
151+
impl<'py> ExactSizeIterator for PyFrozenSetIterator<'py> {
152+
fn len(&self) -> usize {
153+
self.set.len().saturating_sub(self.pos as usize)
151154
}
152155
}
153156
}

src/types/list.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,14 @@ impl<'a> Iterator for PyListIterator<'a> {
322322

323323
#[inline]
324324
fn size_hint(&self) -> (usize, Option<usize>) {
325-
let len = self.list.len();
325+
let len = self.len();
326+
(len, Some(len))
327+
}
328+
}
326329

327-
(
328-
len.saturating_sub(self.index),
329-
Some(len.saturating_sub(self.index)),
330-
)
330+
impl<'a> ExactSizeIterator for PyListIterator<'a> {
331+
fn len(&self) -> usize {
332+
self.list.len().saturating_sub(self.index)
331333
}
332334
}
333335

src/types/set.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ mod impl_ {
169169

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

220220
#[inline]
221221
fn size_hint(&self) -> (usize, Option<usize>) {
222-
let len = self.set.len().unwrap_or_default();
223-
(
224-
len.saturating_sub(self.pos as usize),
225-
Some(len.saturating_sub(self.pos as usize)),
226-
)
222+
let len = self.len();
223+
(len, Some(len))
224+
}
225+
}
226+
227+
impl<'py> ExactSizeIterator for PySetIterator<'py> {
228+
fn len(&self) -> usize {
229+
self.set.len().saturating_sub(self.pos as usize)
227230
}
228231
}
229232
}

src/types/tuple.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,14 @@ impl<'a> Iterator for PyTupleIterator<'a> {
242242

243243
#[inline]
244244
fn size_hint(&self) -> (usize, Option<usize>) {
245-
(
246-
self.length.saturating_sub(self.index as usize),
247-
Some(self.length.saturating_sub(self.index as usize)),
248-
)
245+
let len = self.len();
246+
(len, Some(len))
249247
}
250248
}
251249

252250
impl<'a> ExactSizeIterator for PyTupleIterator<'a> {
253251
fn len(&self) -> usize {
254-
self.length - self.index
252+
self.length.saturating_sub(self.index)
255253
}
256254
}
257255

0 commit comments

Comments
 (0)