Merge pull request #697 from RustPython/more_pyobject

More pyobject
This commit is contained in:
Windel Bouwman authored and GitHub committed 2019-03-19 19:21:44 +01:00
commit 5b6b33b644
7 files changed
+118 -176

No files matched your search

+21 -22
View File
@@ -4,18 +4,20 @@ use std::ops::AddAssign;
use num_bigint::BigInt;
use num_traits::Zero;
use crate::function::PyFuncArgs;
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
use super::objint;
use super::objint::PyIntRef;
use super::objiter;
use super::objtype::PyClassRef;
#[derive(Debug)]
pub struct PyEnumerate {
counter: RefCell<BigInt>,
iterator: PyObjectRef,
}
type PyEnumerateRef = PyRef<PyEnumerate>;
impl PyValue for PyEnumerate {
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
@@ -23,26 +25,23 @@ impl PyValue for PyEnumerate {
}
}
fn enumerate_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(cls, Some(vm.ctx.type_type())), (iterable, None)],
optional = [(start, Some(vm.ctx.int_type()))]
);
let counter = if let Some(x) = start {
objint::get_value(x).clone()
} else {
BigInt::zero()
fn enumerate_new(
cls: PyClassRef,
iterable: PyObjectRef,
start: OptionalArg<PyIntRef>,
vm: &mut VirtualMachine,
) -> PyResult<PyEnumerateRef> {
let counter = match start {
OptionalArg::Present(start) => start.value.clone(),
OptionalArg::Missing => BigInt::zero(),
};
let iterator = objiter::get_iter(vm, iterable)?;
Ok(PyObject::new(
PyEnumerate {
counter: RefCell::new(counter),
iterator,
},
cls.clone(),
))
let iterator = objiter::get_iter(vm, &iterable)?;
PyEnumerate {
counter: RefCell::new(counter.clone()),
iterator,
}
.into_ref_with_type(vm, cls)
}
fn enumerate_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
+4 -6
View File
@@ -4,13 +4,14 @@
use crate::frame::{ExecutionResult, Frame};
use crate::function::PyFuncArgs;
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
use crate::vm::VirtualMachine;
#[derive(Debug)]
pub struct PyGenerator {
frame: PyObjectRef,
}
type PyGeneratorRef = PyRef<PyGenerator>;
impl PyValue for PyGenerator {
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
@@ -37,11 +38,8 @@ pub fn init(context: &PyContext) {
);
}
pub fn new_generator(vm: &mut VirtualMachine, frame: PyObjectRef) -> PyResult {
Ok(PyObject::new(
PyGenerator { frame },
vm.ctx.generator_type.clone(),
))
pub fn new_generator(frame: PyObjectRef, vm: &mut VirtualMachine) -> PyGeneratorRef {
PyGenerator { frame }.into_ref(vm)
}
fn generator_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
+5 -8
View File
@@ -119,14 +119,11 @@ impl PyListRef {
)
}
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
},
vm.ctx.iter_type(),
)
fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue {
PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
}
}
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &mut VirtualMachine) -> PyResult {
+18 -21
View File
@@ -1,14 +1,16 @@
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 super::objtype::PyClassRef;
#[derive(Debug)]
pub struct PyMap {
mapper: PyObjectRef,
iterators: Vec<PyObjectRef>,
}
type PyMapRef = PyRef<PyMap>;
impl PyValue for PyMap {
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
@@ -16,26 +18,21 @@ impl PyValue for PyMap {
}
}
fn map_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
no_kwargs!(vm, args);
let cls = &args.args[0];
if args.args.len() < 3 {
Err(vm.new_type_error("map() must have at least two arguments.".to_owned()))
} else {
let function = &args.args[1];
let iterables = &args.args[2..];
let iterators = iterables
.iter()
.map(|iterable| objiter::get_iter(vm, iterable))
.collect::<Result<Vec<_>, _>>()?;
Ok(PyObject::new(
PyMap {
mapper: function.clone(),
iterators,
},
cls.clone(),
))
fn map_new(
cls: PyClassRef,
function: PyObjectRef,
iterables: Args,
vm: &mut VirtualMachine,
) -> PyResult<PyMapRef> {
let iterators = iterables
.into_iter()
.map(|iterable| objiter::get_iter(vm, &iterable))
.collect::<Result<Vec<_>, _>>()?;
PyMap {
mapper: function.clone(),
iterators,
}
.into_ref_with_type(vm, cls.clone())
}
fn map_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
+59 -105
View File
@@ -7,21 +7,22 @@ use std::collections::{hash_map::DefaultHasher, HashMap};
use std::fmt;
use std::hash::{Hash, Hasher};
use crate::function::PyFuncArgs;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
use super::objbool;
use super::objint;
use super::objiter;
use super::objtype;
use super::objtype::{self, PyClassRef};
#[derive(Default)]
pub struct PySet {
elements: RefCell<HashMap<u64, PyObjectRef>>,
}
pub type PySetRef = PyRef<PySet>;
impl fmt::Debug for PySet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -151,23 +152,20 @@ fn set_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
/* Create a new object of sub-type of set */
fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(cls, None)],
optional = [(iterable, None)]
);
if !objtype::issubclass(cls, &vm.ctx.set_type()) {
fn set_new(
cls: PyClassRef,
iterable: OptionalArg<PyObjectRef>,
vm: &mut VirtualMachine,
) -> PyResult<PySetRef> {
if !objtype::issubclass(cls.as_object(), &vm.ctx.set_type()) {
return Err(vm.new_type_error(format!("{} is not a subtype of set", cls)));
}
let elements: HashMap<u64, PyObjectRef> = match iterable {
None => HashMap::new(),
Some(iterable) => {
OptionalArg::Missing => HashMap::new(),
OptionalArg::Present(iterable) => {
let mut elements = HashMap::new();
let iterator = objiter::get_iter(vm, iterable)?;
let iterator = objiter::get_iter(vm, &iterable)?;
while let Ok(v) = vm.call_method(&iterator, "__next__", vec![]) {
insert_into_set(vm, &mut elements, &v)?;
}
@@ -175,12 +173,10 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
};
Ok(PyObject::new(
PySet {
elements: RefCell::new(elements),
},
cls.clone(),
))
PySet {
elements: RefCell::new(elements),
}
.into_ref_with_type(vm, cls)
}
fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -190,16 +186,12 @@ fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.context().new_int(elements.len()))
}
fn set_copy(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
trace!("set.copy called with: {:?}", args);
arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
let elements = get_elements(s);
Ok(PyObject::new(
PySet {
elements: RefCell::new(elements),
},
vm.ctx.set_type(),
))
fn set_copy(obj: PySetRef, _vm: &mut VirtualMachine) -> PySet {
trace!("set.copy called with: {:?}", obj);
let elements = obj.elements.borrow().clone();
PySet {
elements: RefCell::new(elements),
}
}
fn set_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -335,67 +327,47 @@ fn set_compare_inner(
Ok(vm.new_bool(true))
}
fn set_union(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [
(zelf, Some(vm.ctx.set_type())),
(other, Some(vm.ctx.set_type()))
]
);
fn set_union(zelf: PySetRef, other: PySetRef, _vm: &mut VirtualMachine) -> PySet {
let mut elements = zelf.elements.borrow().clone();
elements.extend(other.elements.borrow().clone());
let mut elements = get_elements(zelf).clone();
elements.extend(get_elements(other).clone());
Ok(PyObject::new(
PySet {
elements: RefCell::new(elements),
},
vm.ctx.set_type(),
))
PySet {
elements: RefCell::new(elements),
}
}
fn set_intersection(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
set_combine_inner(vm, args, SetCombineOperation::Intersection)
fn set_intersection(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult<PySet> {
set_combine_inner(zelf, other, vm, SetCombineOperation::Intersection)
}
fn set_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
set_combine_inner(vm, args, SetCombineOperation::Difference)
fn set_difference(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult<PySet> {
set_combine_inner(zelf, other, vm, SetCombineOperation::Difference)
}
fn set_symmetric_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [
(zelf, Some(vm.ctx.set_type())),
(other, Some(vm.ctx.set_type()))
]
);
fn set_symmetric_difference(
zelf: PySetRef,
other: PySetRef,
vm: &mut VirtualMachine,
) -> PyResult<PySet> {
let mut elements = HashMap::new();
for element in get_elements(zelf).iter() {
let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?;
for element in zelf.elements.borrow().iter() {
let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
if !objbool::get_value(&value) {
elements.insert(element.0.clone(), element.1.clone());
}
}
for element in get_elements(other).iter() {
let value = vm.call_method(zelf, "__contains__", vec![element.1.clone()])?;
for element in other.elements.borrow().iter() {
let value = vm.call_method(zelf.as_object(), "__contains__", vec![element.1.clone()])?;
if !objbool::get_value(&value) {
elements.insert(element.0.clone(), element.1.clone());
}
}
Ok(PyObject::new(
PySet {
elements: RefCell::new(elements),
},
vm.ctx.set_type(),
))
Ok(PySet {
elements: RefCell::new(elements),
})
}
enum SetCombineOperation {
@@ -404,23 +376,15 @@ enum SetCombineOperation {
}
fn set_combine_inner(
zelf: PySetRef,
other: PySetRef,
vm: &mut VirtualMachine,
args: PyFuncArgs,
op: SetCombineOperation,
) -> PyResult {
arg_check!(
vm,
args,
required = [
(zelf, Some(vm.ctx.set_type())),
(other, Some(vm.ctx.set_type()))
]
);
) -> PyResult<PySet> {
let mut elements = HashMap::new();
for element in get_elements(zelf).iter() {
let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?;
for element in zelf.elements.borrow().iter() {
let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
let should_add = match op {
SetCombineOperation::Intersection => objbool::get_value(&value),
SetCombineOperation::Difference => !objbool::get_value(&value),
@@ -430,12 +394,9 @@ fn set_combine_inner(
}
}
Ok(PyObject::new(
PySet {
elements: RefCell::new(elements),
},
vm.ctx.set_type(),
))
Ok(PySet {
elements: RefCell::new(elements),
})
}
fn set_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -557,20 +518,13 @@ fn set_ixor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(zelf.clone())
}
fn set_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.set_type()))]);
let items = get_elements(zelf).values().cloned().collect();
fn set_iter(zelf: PySetRef, vm: &mut VirtualMachine) -> PyIteratorValue {
let items = zelf.elements.borrow().values().cloned().collect();
let set_list = vm.ctx.new_list(items);
let iter_obj = PyObject::new(
PyIteratorValue {
position: Cell::new(0),
iterated_obj: set_list,
},
vm.ctx.iter_type(),
);
Ok(iter_obj)
PyIteratorValue {
position: Cell::new(0),
iterated_obj: set_list,
}
}
fn frozenset_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
+10 -13
View File
@@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};
use crate::function::OptionalArg;
use crate::pyobject::{
IdProtocol, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
IdProtocol, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -13,7 +13,7 @@ use super::objint;
use super::objsequence::{
get_elements, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul,
};
use super::objtype;
use super::objtype::{self, PyClassRef};
#[derive(Default)]
pub struct PyTuple {
@@ -132,14 +132,11 @@ impl PyTupleRef {
Ok(hasher.finish())
}
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
},
vm.ctx.iter_type(),
)
fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue {
PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
}
}
fn len(self, _vm: &mut VirtualMachine) -> usize {
@@ -207,10 +204,10 @@ impl PyTupleRef {
}
fn tuple_new(
cls: PyRef<objtype::PyClass>,
cls: PyClassRef,
iterable: OptionalArg<PyObjectRef>,
vm: &mut VirtualMachine,
) -> PyResult {
) -> PyResult<PyTupleRef> {
if !objtype::issubclass(cls.as_object(), &vm.ctx.tuple_type()) {
return Err(vm.new_type_error(format!("{} is not a subtype of tuple", cls)));
}
@@ -221,7 +218,7 @@ fn tuple_new(
vec![]
};
Ok(PyObject::new(PyTuple::from(elements), cls.into_object()))
PyTuple::from(elements).into_ref_with_type(vm, cls)
}
#[rustfmt::skip] // to avoid line splitting
+1 -1
View File
@@ -353,7 +353,7 @@ impl VirtualMachine {
// If we have a generator, create a new generator
if code_object.is_generator {
objgenerator::new_generator(self, frame)
Ok(objgenerator::new_generator(frame, self).into_object())
} else {
self.run_frame_full(frame)
}