Fix __length_hint__ to return not_implemented

This commit is contained in:
Kangzhi Shi
2021-09-20 10:18:47 +02:00
parent bf04b505b1
commit 329afeaf15
4 changed files with 23 additions and 17 deletions

View File

@@ -742,16 +742,14 @@ impl PyValue for PyByteArrayIterator {
#[pyimpl(with(SlotIterator))]
impl PyByteArrayIterator {
#[pymethod(magic)]
fn length_hint(&self, vm: &VirtualMachine) -> PyResult {
fn length_hint(&self, vm: &VirtualMachine) -> PyObjectRef {
self.internal.length_hint(
|| {
Ok(self
.internal
self.internal
.obj
.read()
.payload::<PyByteArray>()
.unwrap()
.len())
.map(|x| x.len())
},
vm,
)

View File

@@ -594,9 +594,15 @@ impl PyValue for PyBytesIterator {
#[pyimpl(with(SlotIterator))]
impl PyBytesIterator {
#[pymethod(magic)]
fn length_hint(&self, vm: &VirtualMachine) -> PyResult {
fn length_hint(&self, vm: &VirtualMachine) -> PyObjectRef {
self.internal.length_hint(
|| Ok(self.internal.obj.read().payload::<PyBytes>().unwrap().len()),
|| {
self.internal
.obj
.read()
.payload::<PyBytes>()
.map(|x| x.len())
},
vm,
)
}

View File

@@ -79,18 +79,21 @@ impl PositionIterInternal {
}
}
pub fn length_hint<F>(&self, f: F, vm: &VirtualMachine) -> PyResult
pub fn length_hint<F>(&self, f: F, vm: &VirtualMachine) -> PyObjectRef
where
F: FnOnce() -> PyResult<usize>,
F: FnOnce() -> Option<usize>,
{
let len = if self.is_active(vm) {
let pos = self.position.load();
let obj_len = f()?;
obj_len.saturating_sub(pos)
if let Some(obj_len) = f() {
obj_len.saturating_sub(pos)
} else {
return vm.ctx.not_implemented();
}
} else {
0
};
Ok(PyInt::from(len).into_object(vm))
PyInt::from(len).into_object(vm)
}
}
@@ -127,11 +130,10 @@ impl PySequenceIterator {
}
#[pymethod(magic)]
fn length_hint(&self, vm: &VirtualMachine) -> PyResult {
fn length_hint(&self, vm: &VirtualMachine) -> PyObjectRef {
self.internal.length_hint(
|| {
vm.obj_len(&self.internal.obj.read())
.map_err(|_| vm.new_not_implemented_error("".to_owned()))
vm.obj_len(&self.internal.obj.read()).ok()
},
vm,
)

View File

@@ -331,9 +331,9 @@ impl PyValue for PyTupleIterator {
#[pyimpl(with(SlotIterator))]
impl PyTupleIterator {
#[pymethod(magic)]
fn length_hint(&self, vm: &VirtualMachine) -> PyResult {
fn length_hint(&self, vm: &VirtualMachine) -> PyObjectRef {
self.internal.length_hint(
|| Ok(self.internal.obj.read().payload::<PyTuple>().unwrap().len()),
|| self.internal.obj.read().payload::<PyTuple>().map(|x| x.len()),
vm,
)
}