mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Unify object kinds tuple and list into sequence.
This commit is contained in:
1 parent
b6a88cc3d5
commit
d72abebdd0
12 files changed
+72
-117
No files matched your search
+10
-20
@@ -297,26 +297,16 @@ fn builtin_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn builtin_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, None)]);
|
||||
match obj.borrow().kind {
|
||||
PyObjectKind::Dict { ref elements } => {
|
||||
Ok(vm.context().new_int(elements.len().to_bigint().unwrap()))
|
||||
}
|
||||
PyObjectKind::Tuple { ref elements } => {
|
||||
Ok(vm.context().new_int(elements.len().to_bigint().unwrap()))
|
||||
}
|
||||
_ => {
|
||||
let len_method_name = "__len__".to_string();
|
||||
match vm.get_method(obj.clone(), &len_method_name) {
|
||||
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
|
||||
Err(..) => Err(vm.context().new_str(
|
||||
format!(
|
||||
"TypeError: object of this {:?} type has no method {:?}",
|
||||
obj, len_method_name
|
||||
)
|
||||
.to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
let len_method_name = "__len__".to_string();
|
||||
match vm.get_method(obj.clone(), &len_method_name) {
|
||||
Ok(value) => vm.invoke(value, PyFuncArgs::default()),
|
||||
Err(..) => Err(vm.context().new_str(
|
||||
format!(
|
||||
"TypeError: object of this {:?} type has no method {:?}",
|
||||
obj, len_method_name
|
||||
)
|
||||
.to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::obj::objlist;
|
||||
use super::obj::objsequence;
|
||||
use super::obj::objstr;
|
||||
use super::obj::objtuple;
|
||||
use super::obj::objtype;
|
||||
use super::pyobject::{
|
||||
create_type, AttributeProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
@@ -25,11 +24,11 @@ pub fn print_exception(vm: &mut VirtualMachine, exc: &PyObjectRef) {
|
||||
if let Some(tb) = exc.get_attr("__traceback__") {
|
||||
println!("Traceback (most recent call last):");
|
||||
if objtype::isinstance(&tb, &vm.ctx.list_type()) {
|
||||
let mut elements = objlist::get_elements(&tb).to_vec();
|
||||
let mut elements = objsequence::get_elements(&tb).to_vec();
|
||||
elements.reverse();
|
||||
for element in elements.iter() {
|
||||
if objtype::isinstance(&element, &vm.ctx.tuple_type()) {
|
||||
let element = objtuple::get_elements(&element);
|
||||
let element = objsequence::get_elements(&element);
|
||||
let filename = if let Ok(x) = vm.to_str(&element[0]) {
|
||||
objstr::get_value(&x)
|
||||
} else {
|
||||
|
||||
+6
-11
@@ -8,8 +8,9 @@ use std::path::PathBuf;
|
||||
|
||||
use self::rustpython_parser::parser;
|
||||
use super::compile;
|
||||
use super::pyobject::{DictProtocol, PyObjectKind, PyResult};
|
||||
use super::pyobject::{DictProtocol, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
use obj::{objsequence, objstr};
|
||||
|
||||
fn import_uncached_module(
|
||||
vm: &mut VirtualMachine,
|
||||
@@ -78,16 +79,10 @@ pub fn import(
|
||||
|
||||
fn find_source(vm: &VirtualMachine, current_path: PathBuf, name: &str) -> Result<PathBuf, String> {
|
||||
let sys_path = vm.sys_module.get_item("path").unwrap();
|
||||
let mut paths: Vec<PathBuf> = match sys_path.borrow().kind {
|
||||
PyObjectKind::List { ref elements } => elements
|
||||
.iter()
|
||||
.filter_map(|item| match item.borrow().kind {
|
||||
PyObjectKind::String { ref value } => Some(PathBuf::from(value)),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
_ => panic!("sys.path unexpectedly not a list"),
|
||||
};
|
||||
let mut paths: Vec<PathBuf> = objsequence::get_elements(&sys_path)
|
||||
.iter()
|
||||
.map(|item| PathBuf::from(objstr::get_value(item)))
|
||||
.collect();
|
||||
|
||||
paths.insert(0, current_path);
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
|
||||
let result = match obj.borrow().kind {
|
||||
PyObjectKind::Integer { ref value } => !value.is_zero(),
|
||||
PyObjectKind::Float { value } => value != 0.0,
|
||||
PyObjectKind::List { ref elements } => !elements.is_empty(),
|
||||
PyObjectKind::Tuple { ref elements } => !elements.is_empty(),
|
||||
PyObjectKind::Sequence { ref elements } => !elements.is_empty(),
|
||||
PyObjectKind::Dict { ref elements } => !elements.is_empty(),
|
||||
PyObjectKind::String { ref value } => !value.is_empty(),
|
||||
PyObjectKind::None { .. } => false,
|
||||
|
||||
@@ -127,7 +127,7 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
{
|
||||
let iterated_obj = &*iterated_obj_ref.borrow_mut();
|
||||
match iterated_obj.kind {
|
||||
PyObjectKind::List { ref elements } => {
|
||||
PyObjectKind::Sequence { ref elements } => {
|
||||
if *position < elements.len() {
|
||||
let obj_ref = elements[*position].clone();
|
||||
*position += 1;
|
||||
|
||||
+4
-26
@@ -5,13 +5,13 @@ use super::super::pyobject::{
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objsequence::{get_item, seq_equal, PySliceableSequence};
|
||||
use super::objsequence::{
|
||||
get_elements, get_item, get_mut_elements, seq_equal, PySliceableSequence,
|
||||
};
|
||||
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:
|
||||
fn set_item(
|
||||
@@ -33,28 +33,6 @@ fn set_item(
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
arg_check!(
|
||||
vm,
|
||||
@@ -74,7 +52,7 @@ fn list_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectKind::List { elements: elements },
|
||||
PyObjectKind::Sequence { elements: elements },
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ use super::super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult, Type
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objbool;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::marker::Sized;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub trait PySliceableSequence {
|
||||
fn do_slice(&self, start: usize, stop: usize) -> Self;
|
||||
@@ -85,10 +87,7 @@ pub fn get_item(
|
||||
step: _,
|
||||
} => Ok(PyObject::new(
|
||||
match &(sequence.borrow()).kind {
|
||||
PyObjectKind::Tuple { elements: _ } => PyObjectKind::Tuple {
|
||||
elements: elements.to_vec().get_slice_items(&subscript),
|
||||
},
|
||||
PyObjectKind::List { elements: _ } => PyObjectKind::List {
|
||||
PyObjectKind::Sequence { elements: _ } => PyObjectKind::Sequence {
|
||||
elements: elements.to_vec().get_slice_items(&subscript),
|
||||
},
|
||||
ref kind => panic!("sequence get_item called for non-sequence: {:?}", kind),
|
||||
@@ -120,3 +119,25 @@ pub fn seq_equal(
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<PyObjectRef>> + 'a {
|
||||
Ref::map(obj.borrow(), |x| {
|
||||
if let PyObjectKind::Sequence { ref elements } = x.kind {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-sequence");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_mut_elements<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<PyObjectRef>> + 'a {
|
||||
RefMut::map(obj.borrow_mut(), |x| {
|
||||
if let PyObjectKind::Sequence { ref mut elements } = x.kind {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-sequence");
|
||||
// TODO: raise proper error?
|
||||
// Err(vm.new_type_error("list.append is called with no list".to_string()))
|
||||
}
|
||||
})
|
||||
}
|
||||
+2
-14
@@ -5,13 +5,11 @@ use super::super::pyobject::{
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objsequence::{get_item, seq_equal};
|
||||
use super::objsequence::{get_elements, get_item, seq_equal};
|
||||
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!(
|
||||
@@ -75,7 +73,7 @@ fn tuple_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectKind::Tuple { elements: elements },
|
||||
PyObjectKind::Sequence { elements: elements },
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
@@ -128,16 +126,6 @@ pub fn tuple_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.new_bool(false))
|
||||
}
|
||||
|
||||
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) {
|
||||
let ref tuple_type = context.tuple_type;
|
||||
tuple_type.set_attr("__eq__", context.new_rustfunc(tuple_eq));
|
||||
|
||||
+10
-25
@@ -323,13 +323,16 @@ impl PyContext {
|
||||
|
||||
pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyObjectKind::Tuple { elements: elements },
|
||||
PyObjectKind::Sequence { elements: elements },
|
||||
self.tuple_type(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
|
||||
PyObject::new(PyObjectKind::List { elements: elements }, self.list_type())
|
||||
PyObject::new(
|
||||
PyObjectKind::Sequence { elements: elements },
|
||||
self.list_type(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_set(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
|
||||
@@ -673,10 +676,7 @@ pub enum PyObjectKind {
|
||||
Bytes {
|
||||
value: Vec<u8>,
|
||||
},
|
||||
List {
|
||||
elements: Vec<PyObjectRef>,
|
||||
},
|
||||
Tuple {
|
||||
Sequence {
|
||||
elements: Vec<PyObjectRef>,
|
||||
},
|
||||
Dict {
|
||||
@@ -737,9 +737,8 @@ impl fmt::Debug for PyObjectKind {
|
||||
&PyObjectKind::Integer { ref value } => write!(f, "int {}", value),
|
||||
&PyObjectKind::Float { ref value } => write!(f, "float {}", value),
|
||||
&PyObjectKind::Complex { ref value } => write!(f, "complex {}", value),
|
||||
&PyObjectKind::Bytes { ref value } => write!(f, "bytes {:?}", value),
|
||||
&PyObjectKind::List { elements: _ } => write!(f, "list"),
|
||||
&PyObjectKind::Tuple { elements: _ } => write!(f, "tuple"),
|
||||
&PyObjectKind::Bytes { ref value } => write!(f, "bytes/bytearray {:?}", value),
|
||||
&PyObjectKind::Sequence { elements: _ } => write!(f, "list or tuple"),
|
||||
&PyObjectKind::Dict { elements: _ } => write!(f, "dict"),
|
||||
&PyObjectKind::Set { elements: _ } => write!(f, "set"),
|
||||
&PyObjectKind::Iterator {
|
||||
@@ -790,28 +789,14 @@ impl PyObject {
|
||||
PyObjectKind::Float { ref value } => format!("{:?}", value),
|
||||
PyObjectKind::Complex { ref value } => format!("{:?}", value),
|
||||
PyObjectKind::Bytes { ref value } => format!("b'{:?}'", value),
|
||||
PyObjectKind::List { ref elements } => format!(
|
||||
"[{}]",
|
||||
PyObjectKind::Sequence { ref elements } => format!(
|
||||
"(/[{}]/)",
|
||||
elements
|
||||
.iter()
|
||||
.map(|elem| elem.borrow().str())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
PyObjectKind::Tuple { ref elements } => {
|
||||
if elements.len() == 1 {
|
||||
format!("({},)", elements[0].borrow().str())
|
||||
} else {
|
||||
format!(
|
||||
"({})",
|
||||
elements
|
||||
.iter()
|
||||
.map(|elem| elem.borrow().str())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
PyObjectKind::Dict { ref elements } => format!(
|
||||
"{{ {} }}",
|
||||
elements
|
||||
|
||||
@@ -5,7 +5,7 @@ use serde::de::{DeserializeSeed, Visitor};
|
||||
use serde::ser::{SerializeMap, SerializeSeq};
|
||||
use serde_json;
|
||||
|
||||
use super::super::obj::{objbool, objdict, objfloat, objint, objlist, objstr, objtuple, objtype};
|
||||
use super::super::obj::{objbool, objdict, objfloat, objint, objsequence, objstr, objtype};
|
||||
use super::super::pyobject::{
|
||||
DictProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
@@ -54,10 +54,10 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
|
||||
// Allthough this may seem nice, it does not give the right result:
|
||||
// v.serialize(serializer)
|
||||
} else if objtype::isinstance(self.pyobject, &self.ctx.list_type()) {
|
||||
let elements = objlist::get_elements(self.pyobject);
|
||||
let elements = objsequence::get_elements(self.pyobject);
|
||||
serialize_seq_elements(serializer, &elements)
|
||||
} else if objtype::isinstance(self.pyobject, &self.ctx.tuple_type()) {
|
||||
let elements = objtuple::get_elements(self.pyobject);
|
||||
let elements = objsequence::get_elements(self.pyobject);
|
||||
serialize_seq_elements(serializer, &elements)
|
||||
} else if objtype::isinstance(self.pyobject, &self.ctx.dict_type()) {
|
||||
let elements = objdict::get_elements(self.pyobject);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Dynamic type creation and names for built in types.
|
||||
*/
|
||||
|
||||
use super::super::obj::{objstr, objtuple, objtype};
|
||||
use super::super::obj::{objsequence, objstr, objtype};
|
||||
use super::super::pyobject::{
|
||||
DictProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
@@ -22,7 +22,7 @@ fn types_new_class(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let bases = match bases {
|
||||
Some(b) => {
|
||||
if objtype::isinstance(b, &vm.ctx.tuple_type()) {
|
||||
objtuple::get_elements(b).to_vec()
|
||||
objsequence::get_elements(b).to_vec()
|
||||
} else {
|
||||
return Err(vm.new_type_error("Bases must be a tuple".to_string()));
|
||||
}
|
||||
@@ -39,6 +39,7 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
|
||||
// Number theory functions:
|
||||
py_mod.set_item("new_class", ctx.new_rustfunc(types_new_class));
|
||||
py_mod.set_item("FunctionType", ctx.function_type());
|
||||
py_mod.set_item("LambdaType", ctx.function_type());
|
||||
|
||||
py_mod
|
||||
}
|
||||
+4
-5
@@ -13,9 +13,8 @@ use super::bytecode;
|
||||
use super::frame::{copy_code, Frame};
|
||||
use super::obj::objgenerator;
|
||||
use super::obj::objiter;
|
||||
use super::obj::objlist;
|
||||
use super::obj::objsequence;
|
||||
use super::obj::objstr;
|
||||
use super::obj::objtuple;
|
||||
use super::obj::objtype;
|
||||
use super::pyobject::{
|
||||
AttributeProtocol, DictProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult,
|
||||
@@ -344,7 +343,7 @@ impl VirtualMachine {
|
||||
// function definition calls for
|
||||
if nargs < nexpected_args {
|
||||
let available_defaults = match defaults.borrow().kind {
|
||||
PyObjectKind::Tuple { ref elements } => elements.clone(),
|
||||
PyObjectKind::Sequence { ref elements } => elements.clone(),
|
||||
PyObjectKind::None => vec![],
|
||||
_ => panic!("function defaults not tuple or None"),
|
||||
};
|
||||
@@ -405,9 +404,9 @@ impl VirtualMachine {
|
||||
) -> Result<Vec<PyObjectRef>, PyObjectRef> {
|
||||
// Extract elements from item, if possible:
|
||||
let elements = if objtype::isinstance(value, &self.ctx.tuple_type()) {
|
||||
objtuple::get_elements(value).to_vec()
|
||||
objsequence::get_elements(value).to_vec()
|
||||
} else if objtype::isinstance(value, &self.ctx.list_type()) {
|
||||
objlist::get_elements(value).to_vec()
|
||||
objsequence::get_elements(value).to_vec()
|
||||
} else {
|
||||
let iter = objiter::get_iter(self, value)?;
|
||||
objiter::get_all(self, &iter)?
|
||||
|
||||
Reference in new issue
Block a user