Skip to content

Commit e48525f

Browse files
adamreicholddavidhewitt
authored andcommitted
Add more implementations of ExactSizeIterator when iterating built-in Python data structures.
1 parent ba82788 commit e48525f

File tree

6 files changed

+36
-23
lines changed

6 files changed

+36
-23
lines changed

newsfragments/2676.added.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implemented `ExactSizeIterator` for `PyListIterator`, `PyDictIterator`, `PySetIterator` and `PyFrozenSetIterator`

src/types/dict.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,17 @@ impl<'py> Iterator for PyDictIterator<'py> {
308308

309309
#[inline]
310310
fn size_hint(&self) -> (usize, Option<usize>) {
311-
let len = self.len as usize;
311+
let len = self.len();
312312
(len, Some(len))
313313
}
314314
}
315315

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

src/types/frozenset.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ mod impl_ {
117117
}
118118

119119
pub struct PyFrozenSetIterator<'py> {
120-
set: &'py PyAny,
120+
set: &'py PyFrozenSet,
121121
pos: ffi::Py_ssize_t,
122122
}
123123

@@ -141,11 +141,14 @@ mod impl_ {
141141

142142
#[inline]
143143
fn size_hint(&self) -> (usize, Option<usize>) {
144-
let len = self.set.len().unwrap_or_default();
145-
(
146-
len.saturating_sub(self.pos as usize),
147-
Some(len.saturating_sub(self.pos as usize)),
148-
)
144+
let len = self.len();
145+
(len, Some(len))
146+
}
147+
}
148+
149+
impl<'py> ExactSizeIterator for PyFrozenSetIterator<'py> {
150+
fn len(&self) -> usize {
151+
self.set.len().saturating_sub(self.pos as usize)
149152
}
150153
}
151154
}

src/types/list.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,14 @@ impl<'a> Iterator for PyListIterator<'a> {
321321

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

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

src/types/set.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ mod impl_ {
165165
mod impl_ {
166166
use super::*;
167167
pub struct PySetIterator<'py> {
168-
set: &'py super::PyAny,
168+
set: &'py super::PySet,
169169
pos: ffi::Py_ssize_t,
170170
used: ffi::Py_ssize_t,
171171
}
@@ -215,11 +215,14 @@ mod impl_ {
215215

216216
#[inline]
217217
fn size_hint(&self) -> (usize, Option<usize>) {
218-
let len = self.set.len().unwrap_or_default();
219-
(
220-
len.saturating_sub(self.pos as usize),
221-
Some(len.saturating_sub(self.pos as usize)),
222-
)
218+
let len = self.len();
219+
(len, Some(len))
220+
}
221+
}
222+
223+
impl<'py> ExactSizeIterator for PySetIterator<'py> {
224+
fn len(&self) -> usize {
225+
self.set.len().saturating_sub(self.pos as usize)
223226
}
224227
}
225228
}

src/types/tuple.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,14 @@ impl<'a> Iterator for PyTupleIterator<'a> {
241241

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

251249
impl<'a> ExactSizeIterator for PyTupleIterator<'a> {
252250
fn len(&self) -> usize {
253-
self.length - self.index
251+
self.length.saturating_sub(self.index)
254252
}
255253
}
256254

0 commit comments

Comments
 (0)