mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Call __length_hint__ on object to be extracted.
This commit is contained in:
1 parent
54e8c71c3e
commit
022eb28c09
4 files changed
+23
-13
No files matched your search
Vendored
-2
@@ -252,8 +252,6 @@ class NoneLengthHint(object):
|
||||
|
||||
class TestLengthHintExceptions(unittest.TestCase):
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_issue1242657(self):
|
||||
self.assertRaises(RuntimeError, list, BadLen())
|
||||
self.assertRaises(RuntimeError, list, BadLengthHint())
|
||||
|
||||
+7
-8
@@ -6,7 +6,7 @@ use crate::builtins::int::{self, PyInt};
|
||||
use crate::builtins::iter::PySequenceIterator;
|
||||
use crate::exceptions::PyBaseExceptionRef;
|
||||
use crate::vm::VirtualMachine;
|
||||
use crate::{IdProtocol, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol};
|
||||
use crate::{IdProtocol, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use num_traits::Signed;
|
||||
|
||||
/*
|
||||
@@ -73,16 +73,15 @@ pub fn get_next_object(
|
||||
}
|
||||
}
|
||||
|
||||
/* Retrieve all elements from an iterator */
|
||||
pub fn get_all<T: TryFromObject>(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> PyResult<Vec<T>> {
|
||||
try_map(vm, iter_obj, |obj| T::try_from_object(vm, obj))
|
||||
}
|
||||
|
||||
pub fn try_map<F, R>(vm: &VirtualMachine, iter_obj: &PyObjectRef, mut f: F) -> PyResult<Vec<R>>
|
||||
pub fn try_map<F, R>(
|
||||
vm: &VirtualMachine,
|
||||
iter_obj: &PyObjectRef,
|
||||
cap: usize,
|
||||
mut f: F,
|
||||
) -> PyResult<Vec<R>>
|
||||
where
|
||||
F: FnMut(PyObjectRef) -> PyResult<R>,
|
||||
{
|
||||
let cap = length_hint(vm, iter_obj.clone())?.unwrap_or(0);
|
||||
// TODO: fix extend to do this check (?), see test_extend in Lib/test/list_tests.py,
|
||||
// https://github.com/python/cpython/blob/v3.9.0/Objects/listobject.c#L922-L928
|
||||
if cap >= isize::max_value() as usize {
|
||||
|
||||
@@ -204,7 +204,6 @@ mod _collections {
|
||||
|
||||
#[pymethod]
|
||||
fn extend(&self, iter: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
// TODO: use length_hint here and for extendleft
|
||||
self.state.fetch_add(1);
|
||||
let max_len = self.maxlen;
|
||||
let mut elements: Vec<PyObjectRef> = vm.extract_elements(&iter)?;
|
||||
|
||||
+16
-2
@@ -1261,7 +1261,13 @@ impl VirtualMachine {
|
||||
.collect()
|
||||
} else {
|
||||
let iter = iterator::get_iter(self, value.clone())?;
|
||||
iterator::try_map(self, &iter, |obj| func(obj))
|
||||
let cap = match iterator::length_hint(self, value.clone()) {
|
||||
Err(e) if e.class().is(&self.ctx.exceptions.runtime_error) => return Err(e),
|
||||
Ok(Some(value)) => value,
|
||||
// Use a power of 2 as a default capacity.
|
||||
_ => 4,
|
||||
};
|
||||
iterator::try_map(self, &iter, cap, |obj| func(obj))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1303,7 +1309,15 @@ impl VirtualMachine {
|
||||
// TODO: put internal iterable type
|
||||
obj => {
|
||||
let iter = iterator::get_iter(self, obj.clone())?;
|
||||
Ok(iterator::try_map(self, &iter, f))
|
||||
let cap = match iterator::length_hint(self, obj.clone()) {
|
||||
Err(e) if e.class().is(&self.ctx.exceptions.runtime_error) => {
|
||||
return Ok(Err(e))
|
||||
}
|
||||
Ok(Some(value)) => value,
|
||||
// Use a power of 2 as a default capacity.
|
||||
_ => 4,
|
||||
};
|
||||
Ok(iterator::try_map(self, &iter, cap, f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user