mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Use __setitem__ to store elements in list. Also refactor get_elements to return a reference to the elements, not a copy.
This commit is contained in:
@@ -25,8 +25,8 @@ fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
let val = if objtype::isinstance(arg, &vm.ctx.list_type()) {
|
||||
let mut data_bytes = vec![];
|
||||
for elem in objlist::get_elements(arg) {
|
||||
let v = objint::to_int(vm, &elem, 10)?;
|
||||
for elem in objlist::get_elements(arg).iter() {
|
||||
let v = objint::to_int(vm, elem, 10)?;
|
||||
data_bytes.push(v.to_u8().unwrap());
|
||||
}
|
||||
data_bytes
|
||||
|
||||
@@ -51,13 +51,9 @@ fn dict_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let elements = get_elements(o);
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements {
|
||||
match vm.to_repr(elem.1) {
|
||||
Ok(s) => {
|
||||
let value_str = objstr::get_value(&s);
|
||||
str_parts.push(format!("{}: {}", elem.0, value_str));
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
let s = vm.to_repr(&elem.1)?;
|
||||
let value_str = objstr::get_value(&s);
|
||||
str_parts.push(format!("{}: {}", elem.0, value_str));
|
||||
}
|
||||
|
||||
let s = format!("{{ {} }}", str_parts.join(", "));
|
||||
|
||||
@@ -11,9 +11,11 @@ use super::objstr;
|
||||
use super::objtype;
|
||||
use num_bigint::ToBigInt;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
// set_item:
|
||||
pub fn set_item(
|
||||
fn set_item(
|
||||
vm: &mut VirtualMachine,
|
||||
l: &mut Vec<PyObjectRef>,
|
||||
idx: PyObjectRef,
|
||||
@@ -32,12 +34,26 @@ pub fn set_item(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
if let PyObjectKind::List { elements } = &obj.borrow().kind {
|
||||
elements.to_vec()
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-list");
|
||||
}
|
||||
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<PyObjectRef>> + 'a {
|
||||
Ref::map(obj.borrow(), |x| {
|
||||
if let PyObjectKind::List { ref elements } = x.kind {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-list");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_mut_elements<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<PyObjectRef>> + 'a {
|
||||
RefMut::map(obj.borrow_mut(), |x| {
|
||||
if let PyObjectKind::List { ref mut elements } = x.kind {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-list");
|
||||
// TODO: raise proper error?
|
||||
// Err(vm.new_type_error("list.append is called with no list".to_string()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn list_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -76,7 +92,7 @@ fn list_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(other, &vm.ctx.list_type()) {
|
||||
let zelf = get_elements(zelf);
|
||||
let other = get_elements(other);
|
||||
seq_equal(vm, zelf, other)?
|
||||
seq_equal(vm, &zelf, &other)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@@ -105,7 +121,7 @@ fn list_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
let elements = get_elements(o);
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements {
|
||||
for elem in elements.iter() {
|
||||
let s = vm.to_repr(elem)?;
|
||||
str_parts.push(objstr::get_value(&s));
|
||||
}
|
||||
@@ -121,25 +137,17 @@ pub fn list_append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(list, Some(vm.ctx.list_type())), (x, None)]
|
||||
);
|
||||
let mut list_obj = list.borrow_mut();
|
||||
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
|
||||
elements.push(x.clone());
|
||||
Ok(vm.get_none())
|
||||
} else {
|
||||
Err(vm.new_type_error("list.append is called with no list".to_string()))
|
||||
}
|
||||
let mut elements = get_mut_elements(list);
|
||||
elements.push(x.clone());
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
fn list_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("list.clear called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(list, Some(vm.ctx.list_type()))]);
|
||||
let mut list_obj = list.borrow_mut();
|
||||
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
|
||||
elements.clear();
|
||||
Ok(vm.get_none())
|
||||
} else {
|
||||
Err(vm.new_type_error("list.clear is called with no list".to_string()))
|
||||
}
|
||||
let mut elements = get_mut_elements(list);
|
||||
elements.clear();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
pub fn list_extend(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -149,13 +157,9 @@ pub fn list_extend(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
required = [(list, Some(vm.ctx.list_type())), (x, None)]
|
||||
);
|
||||
let mut new_elements = vm.extract_elements(x)?;
|
||||
let mut list_obj = list.borrow_mut();
|
||||
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
|
||||
elements.append(&mut new_elements);
|
||||
Ok(vm.get_none())
|
||||
} else {
|
||||
Err(vm.new_type_error("list.extend is called with no list".to_string()))
|
||||
}
|
||||
let mut elements = get_mut_elements(list);
|
||||
elements.append(&mut new_elements);
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -168,13 +172,9 @@ fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn list_reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("list.reverse called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(list, Some(vm.ctx.list_type()))]);
|
||||
let mut list_obj = list.borrow_mut();
|
||||
if let PyObjectKind::List { ref mut elements } = list_obj.kind {
|
||||
elements.reverse();
|
||||
Ok(vm.get_none())
|
||||
} else {
|
||||
Err(vm.new_type_error("list.reverse is called with no list".to_string()))
|
||||
}
|
||||
let mut elements = get_mut_elements(list);
|
||||
elements.reverse();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
fn list_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -208,12 +208,23 @@ fn list_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
get_item(vm, list, &get_elements(list), needle.clone())
|
||||
}
|
||||
|
||||
fn list_setitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(list, Some(vm.ctx.list_type())), (key, None), (value, None)]
|
||||
);
|
||||
let mut elements = get_mut_elements(list);
|
||||
set_item(vm, &mut elements, key.clone(), value.clone())
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref list_type = context.list_type;
|
||||
list_type.set_attr("__add__", context.new_rustfunc(list_add));
|
||||
list_type.set_attr("__contains__", context.new_rustfunc(list_contains));
|
||||
list_type.set_attr("__eq__", context.new_rustfunc(list_eq));
|
||||
list_type.set_attr("__getitem__", context.new_rustfunc(list_getitem));
|
||||
list_type.set_attr("__setitem__", context.new_rustfunc(list_setitem));
|
||||
list_type.set_attr("__len__", context.new_rustfunc(list_len));
|
||||
list_type.set_attr("__new__", context.new_rustfunc(list_new));
|
||||
list_type.set_attr("__repr__", context.new_rustfunc(list_repr));
|
||||
|
||||
@@ -104,8 +104,8 @@ pub fn get_item(
|
||||
|
||||
pub fn seq_equal(
|
||||
vm: &mut VirtualMachine,
|
||||
zelf: Vec<PyObjectRef>,
|
||||
other: Vec<PyObjectRef>,
|
||||
zelf: &Vec<PyObjectRef>,
|
||||
other: &Vec<PyObjectRef>,
|
||||
) -> Result<bool, PyObjectRef> {
|
||||
if zelf.len() == other.len() {
|
||||
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
|
||||
|
||||
@@ -100,7 +100,7 @@ fn set_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let elements = get_elements(o);
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements.values() {
|
||||
let part = vm.to_repr(elem.clone())?;
|
||||
let part = vm.to_repr(elem)?;
|
||||
str_parts.push(objstr::get_value(&part));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ use super::objstr;
|
||||
use super::objtype;
|
||||
use num_bigint::ToBigInt;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::cell::Ref;
|
||||
use std::ops::Deref;
|
||||
|
||||
fn tuple_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
@@ -20,7 +22,7 @@ fn tuple_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(other, &vm.ctx.tuple_type()) {
|
||||
let zelf = get_elements(zelf);
|
||||
let other = get_elements(other);
|
||||
seq_equal(vm, zelf, other)?
|
||||
seq_equal(vm, &zelf, &other)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@@ -35,7 +37,7 @@ fn tuple_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let len: usize = elements.len();
|
||||
let mut mult = 0xf4243;
|
||||
|
||||
for elem in &elements {
|
||||
for elem in elements.iter() {
|
||||
let y: usize = objint::get_value(&vm.call_method(elem, "__hash__", vec![])?)
|
||||
.to_usize()
|
||||
.unwrap();
|
||||
@@ -59,7 +61,7 @@ fn tuple_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let elements = get_elements(zelf);
|
||||
|
||||
let mut str_parts = vec![];
|
||||
for elem in elements {
|
||||
for elem in elements.iter() {
|
||||
match vm.to_repr(elem) {
|
||||
Ok(s) => str_parts.push(objstr::get_value(&s)),
|
||||
Err(err) => return Err(err),
|
||||
@@ -103,12 +105,14 @@ pub fn tuple_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.new_bool(false))
|
||||
}
|
||||
|
||||
pub fn get_elements(obj: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
if let PyObjectKind::Tuple { elements } = &obj.borrow().kind {
|
||||
elements.to_vec()
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-tuple");
|
||||
}
|
||||
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<PyObjectRef>> + 'a {
|
||||
Ref::map(obj.borrow(), |x| {
|
||||
if let PyObjectKind::Tuple { ref elements } = x.kind {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-tuple");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
Reference in New Issue
Block a user