manually loop for list

This commit is contained in:
Kangzhi Shi authored and GitHub committed 2020-10-20 06:53:11 +00:00
1 parent 443e9b17f7
commit 03eed121fb
4 files changed
+36 -15

No files matched your search

-1
View File
@@ -113,7 +113,6 @@ class BaseBytesTest:
b = self.type2test([1, 2, 3])
self.assertEqual(b, b"\x01\x02\x03")
# @unittest.skip("TODO")
def test_from_mutating_list(self):
# Issue #34973: Crash in bytes constructor with mutating list.
class X:
+2 -4
View File
@@ -3,6 +3,7 @@ use itertools::Itertools;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
use crate::anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper};
use crate::builtins::bytearray::PyByteArray;
use crate::builtins::bytes::{PyBytes, PyBytesRef};
use crate::builtins::int::{self, PyInt, PyIntRef};
@@ -14,12 +15,9 @@ use crate::pyobject::{
BorrowValue, Either, PyComparisonValue, PyIterable, PyObjectRef, PyResult, TryFromObject,
TypeProtocol,
};
use crate::sliceable::PySliceableSequence;
use crate::slots::PyComparisonOp;
use crate::vm::VirtualMachine;
use crate::{
anystr::{self, AnyStr, AnyStrContainer, AnyStrWrapper},
sliceable::PySliceableSequence,
};
use rustpython_common::hash;
#[derive(Debug, Default, Clone)]
+2 -2
View File
@@ -80,7 +80,7 @@ pub fn get_all<T: TryFromObject>(vm: &VirtualMachine, iter_obj: &PyObjectRef) ->
pub fn try_map<F, R>(vm: &VirtualMachine, iter_obj: &PyObjectRef, mut f: F) -> PyResult<Vec<R>>
where
F: FnMut(&PyObjectRef) -> PyResult<R>,
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,
@@ -90,7 +90,7 @@ where
}
let mut results = Vec::with_capacity(cap);
while let Some(element) = get_next_object(vm, iter_obj)? {
results.push(f(&element)?);
results.push(f(element)?);
}
results.shrink_to_fit();
Ok(results)
+32 -8
View File
@@ -997,22 +997,46 @@ impl VirtualMachine {
T: TryFromObject,
F: FnMut(T) -> PyResult<R>,
{
self.map_iterable_object(obj, |elem| f(T::try_from_object(self, elem.clone())?))
self.map_iterable_object(obj, |elem| f(T::try_from_object(self, elem)?))
}
pub fn map_iterable_object<F, R>(&self, obj: &PyObjectRef, f: F) -> PyResult<PyResult<Vec<R>>>
pub fn map_iterable_object<F, R>(
&self,
obj: &PyObjectRef,
mut f: F,
) -> PyResult<PyResult<Vec<R>>>
where
F: FnMut(&PyObjectRef) -> PyResult<R>,
F: FnMut(PyObjectRef) -> PyResult<R>,
{
Ok(match_class!(match obj {
ref l @ PyList => l.borrow_value().iter().map(f).collect(),
ref t @ PyTuple => t.borrow_value().iter().map(f).collect(),
match_class!(match obj {
ref l @ PyList => {
let mut i: usize = 0;
let mut results = Vec::with_capacity(l.borrow_value().len());
loop {
let elem = {
let elements = &*l.borrow_value();
if i >= elements.len() {
results.shrink_to_fit();
return Ok(Ok(results));
} else {
elements[i].clone()
}
// free the lock
};
match f(elem) {
Ok(result) => results.push(result),
Err(err) => return Ok(Err(err)),
}
i += 1;
}
}
ref t @ PyTuple => Ok(t.borrow_value().iter().cloned().map(f).collect()),
// TODO: put internal iterable type
obj => {
let iter = iterator::get_iter(self, obj)?;
iterator::try_map(self, &iter, f)
Ok(iterator::try_map(self, &iter, f))
}
}))
})
}
// get_attribute should be used for full attribute access (usually from user code).