Merge remote-tracking branch 'origin/master' into joey/range-getitem-either

This commit is contained in:
Joey
2019-03-23 15:50:12 -07:00
22 changed files with 189 additions and 283 deletions

View File

@@ -7,9 +7,11 @@ use std::fmt;
use crate::bytecode;
use crate::function::PyFuncArgs;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
pub type PyCodeRef = PyRef<PyCode>;
pub struct PyCode {
code: bytecode::CodeObject,
}

View File

@@ -1,13 +1,13 @@
use crate::function::PyFuncArgs;
use crate::pyobject::{
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
};
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine; // Required for arg_check! to use isinstance
use super::objbool;
use super::objiter;
use crate::obj::objtype::PyClassRef;
pub type PyFilterRef = PyRef<PyFilter>;
#[derive(Debug)]
pub struct PyFilter {
predicate: PyObjectRef,
@@ -20,20 +20,19 @@ impl PyValue for PyFilter {
}
}
fn filter_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(cls, None), (function, None), (iterable, None)]
);
let iterator = objiter::get_iter(vm, iterable)?;
Ok(PyObject::new(
PyFilter {
predicate: function.clone(),
iterator,
},
cls.clone(),
))
fn filter_new(
cls: PyClassRef,
function: PyObjectRef,
iterable: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyFilterRef> {
let iterator = objiter::get_iter(vm, &iterable)?;
PyFilter {
predicate: function.clone(),
iterator,
}
.into_ref_with_type(vm, cls)
}
fn filter_next(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {

View File

@@ -4,7 +4,7 @@ use super::objstr;
use super::objtype;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
IntoPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
IntoPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_bigint::ToBigInt;
@@ -155,7 +155,7 @@ impl PyFloatRef {
}
}
fn new_float(cls: PyObjectRef, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn new_float(cls: PyClassRef, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyFloatRef> {
let value = if objtype::isinstance(&arg, &vm.ctx.float_type()) {
get_value(&arg)
} else if objtype::isinstance(&arg, &vm.ctx.int_type()) {
@@ -193,7 +193,7 @@ impl PyFloatRef {
let type_name = objtype::get_type_name(&arg.typ());
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
};
Ok(PyObject::new(PyFloat { value }, cls.clone()))
PyFloat { value }.into_ref_with_type(vm, cls)
}
fn mod_(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {

View File

@@ -1,8 +1,9 @@
use crate::function::PyFuncArgs;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
pub type PyMemoryViewRef = PyRef<PyMemoryView>;
#[derive(Debug)]
pub struct PyMemoryView {
obj: PyObjectRef,
@@ -14,15 +15,13 @@ impl PyValue for PyMemoryView {
}
}
pub fn new_memory_view(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(cls, None), (bytes_object, None)]);
vm.ctx.set_attr(cls, "obj", bytes_object.clone());
Ok(PyObject::new(
PyMemoryView {
obj: bytes_object.clone(),
},
cls.clone(),
))
pub fn new_memory_view(
cls: PyClassRef,
bytes_object: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyMemoryViewRef> {
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
PyMemoryView { obj: bytes_object }.into_ref_with_type(vm, cls)
}
pub fn init(ctx: &PyContext) {

View File

@@ -7,7 +7,7 @@ use crate::obj::objproperty::PropertyBuilder;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
DictProtocol, IdProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
TypeProtocol,
TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -22,7 +22,7 @@ impl PyValue for PyInstance {
pub fn new_instance(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
// more or less __new__ operator
let cls = args.shift();
let cls = PyClassRef::try_from_object(vm, args.shift())?;
Ok(if cls.is(&vm.ctx.object) {
PyObject::new_without_dict(PyInstance, cls)
} else {

View File

@@ -200,7 +200,7 @@ impl<'a> PropertyBuilder<'a> {
deleter: None,
};
PyObject::new(payload, self.ctx.property_type().into_object())
PyObject::new(payload, self.ctx.property_type())
} else {
let payload = PyReadOnlyProperty {
getter: self.getter.expect(
@@ -208,7 +208,7 @@ impl<'a> PropertyBuilder<'a> {
),
};
PyObject::new(payload, self.ctx.readonly_property_type().into_object())
PyObject::new(payload, self.ctx.readonly_property_type())
}
}
}

View File

@@ -163,12 +163,12 @@ pub fn get_item(
if sequence.payload::<PyList>().is_some() {
Ok(PyObject::new(
PyList::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.typ(),
sequence.type_pyref(),
))
} else if sequence.payload::<PyTuple>().is_some() {
Ok(PyObject::new(
PyTuple::from(elements.to_vec().get_slice_items(vm, &subscript)?),
sequence.typ(),
sequence.type_pyref(),
))
} else {
panic!("sequence get_item called for non-sequence")

View File

@@ -1,7 +1,7 @@
use num_bigint::BigInt;
use crate::function::PyFuncArgs;
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
use super::objint;
@@ -57,14 +57,13 @@ fn slice_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok((cls, Some(start), Some(stop), step))
}
}?;
Ok(PyObject::new(
PySlice {
start: start.map(|x| objint::get_value(x).clone()),
stop: stop.map(|x| objint::get_value(x).clone()),
step: step.map(|x| objint::get_value(x).clone()),
},
cls.clone(),
))
PySlice {
start: start.map(|x| objint::get_value(x).clone()),
stop: stop.map(|x| objint::get_value(x).clone()),
step: step.map(|x| objint::get_value(x).clone()),
}
.into_ref_with_type(vm, cls.clone().downcast().unwrap())
.map(|x| x.into_object())
}
fn get_property_value(vm: &VirtualMachine, value: &Option<BigInt>) -> PyResult {

View File

@@ -241,11 +241,12 @@ pub fn type_new_class(
bases.push(vm.ctx.object());
let name = objstr::get_value(name);
new(
typ.clone(),
typ.clone().downcast().unwrap(),
&name,
bases,
objdict::py_dict_to_attributes(dict),
)
.map(|x| x.into_object())
}
pub fn type_call(class: PyClassRef, args: Args, kwargs: KwArgs, vm: &VirtualMachine) -> PyResult {
@@ -365,14 +366,14 @@ fn linearise_mro(mut bases: Vec<Vec<PyClassRef>>) -> Option<Vec<PyClassRef>> {
}
pub fn new(
typ: PyObjectRef,
typ: PyClassRef,
name: &str,
bases: Vec<PyClassRef>,
dict: HashMap<String, PyObjectRef>,
) -> PyResult {
) -> PyResult<PyClassRef> {
let mros = bases.into_iter().map(|x| _mro(&x)).collect();
let mro = linearise_mro(mros).unwrap();
Ok(PyObject {
let new_type = PyObject {
payload: PyClass {
name: String::from(name),
mro,
@@ -380,7 +381,8 @@ pub fn new(
dict: Some(RefCell::new(dict)),
typ,
}
.into_ref())
.into_ref();
Ok(new_type.downcast().unwrap())
}
#[cfg(test)]
@@ -401,23 +403,8 @@ mod tests {
let object: PyClassRef = context.object.clone();
let type_type = &context.type_type;
let a = new(
type_type.clone().into_object(),
"A",
vec![object.clone()],
HashMap::new(),
)
.unwrap();
let b = new(
type_type.clone().into_object(),
"B",
vec![object.clone()],
HashMap::new(),
)
.unwrap();
let a: PyClassRef = a.downcast().unwrap();
let b: PyClassRef = b.downcast().unwrap();
let a = new(type_type.clone(), "A", vec![object.clone()], HashMap::new()).unwrap();
let b = new(type_type.clone(), "B", vec![object.clone()], HashMap::new()).unwrap();
assert_eq!(
map_ids(linearise_mro(vec![

View File

@@ -1,10 +1,12 @@
use crate::function::PyFuncArgs;
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::function::{Args, PyFuncArgs};
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
use super::objiter;
use crate::obj::objtype::PyClassRef;
pub type PyZipRef = PyRef<PyZip>;
#[derive(Debug)]
pub struct PyZip {
iterators: Vec<PyObjectRef>,
@@ -16,15 +18,12 @@ impl PyValue for PyZip {
}
}
fn zip_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
no_kwargs!(vm, args);
let cls = &args.args[0];
let iterables = &args.args[1..];
fn zip_new(cls: PyClassRef, iterables: Args, vm: &VirtualMachine) -> PyResult<PyZipRef> {
let iterators = iterables
.iter()
.map(|iterable| objiter::get_iter(vm, iterable))
.into_iter()
.map(|iterable| objiter::get_iter(vm, &iterable))
.collect::<Result<Vec<_>, _>>()?;
Ok(PyObject::new(PyZip { iterators }, cls.clone()))
PyZip { iterators }.into_ref_with_type(vm, cls)
}
fn zip_next(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {