|
4 | 4 |
|
5 | 5 | use super::{PyInt, PyTupleRef, PyType}; |
6 | 6 | use crate::{ |
7 | | - AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, |
| 7 | + Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, |
8 | 8 | class::PyClassImpl, |
9 | 9 | function::ArgCallable, |
10 | 10 | object::{Traverse, TraverseFn}, |
@@ -199,24 +199,20 @@ impl PySequenceIterator { |
199 | 199 | #[pymethod] |
200 | 200 | fn __length_hint__(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> { |
201 | 201 | vm.with_recursion("in __length_hint__", || { |
202 | | - let obj = { |
| 202 | + let (obj, position) = { |
203 | 203 | let internal = self.internal.lock(); |
204 | 204 | match &internal.status { |
205 | | - IterStatus::Active(obj) => Some(obj.clone()), |
206 | | - IterStatus::Exhausted => None, |
| 205 | + IterStatus::Active(obj) => (Some(obj.clone()), internal.position), |
| 206 | + IterStatus::Exhausted => (None, 0), |
207 | 207 | } |
208 | 208 | }; |
209 | 209 | if let Some(obj) = obj { |
210 | 210 | let seq = obj.sequence_unchecked(); |
211 | | - match seq.length(vm) { |
212 | | - Ok(x) => Ok(PyInt::from(x).into_pyobject(vm)), |
213 | | - Err(err) => { |
214 | | - if err.fast_isinstance(vm.ctx.exceptions.recursion_error) { |
215 | | - Err(err) |
216 | | - } else { |
217 | | - Ok(vm.ctx.not_implemented()) |
218 | | - } |
219 | | - } |
| 211 | + match seq.length_opt(vm) { |
| 212 | + Some(len) => len.map(|len| { |
| 213 | + PyInt::from(len.saturating_sub(position)).into_pyobject(vm) |
| 214 | + }), |
| 215 | + None => Ok(vm.ctx.not_implemented()), |
220 | 216 | } |
221 | 217 | } else { |
222 | 218 | Ok(PyInt::from(0).into_pyobject(vm)) |
|
0 commit comments