Delete DictProtocol. impl ItemProtocol for PyDictRef.

This commit is contained in:
Adam Kelly
2019-04-06 09:41:46 +01:00
parent ee9066a713
commit 7b2d92f495
12 changed files with 78 additions and 59 deletions

View File

@@ -66,6 +66,8 @@ assert type(x) == LengthDict
assert x['word'] == 4
assert x.get('word') is None
assert 5 == eval("a + word", LengthDict())
# An object that hashes to the same value always, and compares equal if any its values match.
class Hashable(object):
def __init__(self, *args):

View File

@@ -20,7 +20,7 @@ use crate::obj::objtype::{self, PyClassRef};
use crate::frame::Scope;
use crate::function::{Args, OptionalArg, PyFuncArgs};
use crate::pyobject::{
DictProtocol, IdProtocol, PyIterable, PyObjectRef, PyResult, PyValue, TryFromObject,
IdProtocol, ItemProtocol, PyIterable, PyObjectRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -804,6 +804,6 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
"__call__",
vec![name_arg, bases, namespace.into_object()],
)?;
cells.set_item("__class__", class.clone(), vm);
cells.set_item("__class__", class.clone(), vm)?;
Ok(class)
}

View File

@@ -21,8 +21,8 @@ use crate::obj::objstr;
use crate::obj::objtype;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
DictProtocol, IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::vm::VirtualMachine;
use itertools::Itertools;
@@ -133,12 +133,12 @@ pub trait NameProtocol {
impl NameProtocol for Scope {
fn load_name(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
for dict in self.locals.iter() {
if let Some(value) = dict.get_item(name, vm) {
if let Some(value) = dict.get_item_option(name, vm).unwrap() {
return Some(value);
}
}
if let Some(value) = self.globals.get_item(name, vm) {
if let Some(value) = self.globals.get_item_option(name, vm).unwrap() {
return Some(value);
}
@@ -147,7 +147,7 @@ impl NameProtocol for Scope {
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
for dict in self.locals.iter().skip(1) {
if let Some(value) = dict.get_item(name, vm) {
if let Some(value) = dict.get_item_option(name, vm).unwrap() {
return Some(value);
}
}
@@ -155,11 +155,11 @@ impl NameProtocol for Scope {
}
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
self.get_locals().set_item(key, value, vm)
self.get_locals().set_item(key, value, vm).unwrap();
}
fn delete_name(&self, vm: &VirtualMachine, key: &str) {
self.get_locals().del_item(key, vm)
self.get_locals().del_item(key, vm).unwrap();
}
}
@@ -394,12 +394,12 @@ impl Frame {
obj.downcast().expect("Need a dictionary to build a map.");
let dict_elements = dict.get_key_value_pairs();
for (key, value) in dict_elements.iter() {
map_obj.set_item(key.clone(), value.clone(), vm);
map_obj.set_item(key.clone(), value.clone(), vm).unwrap();
}
}
} else {
for (key, value) in self.pop_multiple(2 * size).into_iter().tuples() {
map_obj.set_item(key, value, vm)
map_obj.set_item(key, value, vm).unwrap();
}
}

View File

@@ -8,7 +8,7 @@ use std::path::PathBuf;
use crate::compile;
use crate::frame::Scope;
use crate::obj::{objsequence, objstr};
use crate::pyobject::{DictProtocol, ItemProtocol, PyResult};
use crate::pyobject::{ItemProtocol, PyResult};
use crate::util;
use crate::vm::VirtualMachine;
@@ -39,7 +39,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
// trace!("Code object: {:?}", code_obj);
let attrs = vm.ctx.new_dict();
attrs.set_item("__name__", vm.new_str(module.to_string()), vm);
attrs.set_item("__name__", vm.new_str(module.to_string()), vm)?;
vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
Ok(vm.ctx.new_module(module, attrs))
}

View File

@@ -3,8 +3,7 @@ use std::fmt;
use crate::function::{KwArgs, OptionalArg};
use crate::pyobject::{
DictProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyContext, PyObjectRef, PyRef,
PyResult, PyValue,
IntoPyObject, ItemProtocol, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -174,8 +173,8 @@ impl PyDictRef {
self.entries.borrow().get_items()
}
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
self.set_item(key, value, vm)
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.entries.borrow_mut().insert(vm, &key, value)
}
fn getitem(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -223,21 +222,26 @@ impl PyDictRef {
}
}
impl DictProtocol for PyDictRef {
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
let key = key.into_pyobject(vm).unwrap();
self.entries.borrow().get(vm, &key).unwrap()
impl ItemProtocol for PyDictRef {
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
vm.call_method(self.as_object(), "__getitem__", key.into_pyobject(vm)?)
}
// Item set/get:
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
let key = key.into_pyobject(vm).unwrap();
self.entries.borrow_mut().insert(vm, &key, value).unwrap()
fn set_item<T: IntoPyObject>(
&self,
key: T,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
vm.call_method(
self.as_object(),
"__setitem__",
vec![key.into_pyobject(vm)?, value],
)
}
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) {
let key = key.into_pyobject(vm).unwrap();
self.entries.borrow_mut().delete(vm, &key).unwrap();
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
vm.call_method(self.as_object(), "__delitem__", key.into_pyobject(vm)?)
}
}

View File

@@ -6,7 +6,7 @@ use crate::function::PyFuncArgs;
use crate::obj::objproperty::PropertyBuilder;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
DictProtocol, IdProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
IdProtocol, ItemProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -77,7 +77,7 @@ fn object_setattr(
}
if let Some(ref dict) = obj.clone().dict {
dict.set_item(attr_name, value, vm);
dict.set_item(attr_name, value, vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
@@ -98,7 +98,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
}
if let Some(ref dict) = obj.dict {
dict.del_item(attr_name, vm);
dict.del_item(attr_name, vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
@@ -208,7 +208,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
}
}
if let Some(obj_attr) = object_getattr(&obj, &name, &vm) {
if let Some(obj_attr) = object_getattr(&obj, &name, &vm)? {
Ok(obj_attr)
} else if let Some(attr) = objtype::class_get_attr(&cls, &name) {
vm.call_get_descriptor(attr, obj)
@@ -219,11 +219,15 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
}
}
fn object_getattr(obj: &PyObjectRef, attr_name: &str, vm: &VirtualMachine) -> Option<PyObjectRef> {
fn object_getattr(
obj: &PyObjectRef,
attr_name: &str,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
if let Some(ref dict) = obj.dict {
dict.get_item(attr_name, vm)
dict.get_item_option(attr_name, vm)
} else {
None
Ok(None)
}
}

View File

@@ -12,7 +12,7 @@ use crate::obj::objfunction::PyMethod;
use crate::obj::objstr;
use crate::obj::objtype::{PyClass, PyClassRef};
use crate::pyobject::{
DictProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -124,7 +124,7 @@ fn super_new(
} else {
let frame = vm.current_frame().expect("no current frame for super()");
if let Some(first_arg) = frame.code.arg_names.get(0) {
match vm.get_locals().get_item(first_arg, vm) {
match vm.get_locals().get_item_option(first_arg, vm)? {
Some(obj) => obj.clone(),
_ => {
return Err(vm

View File

@@ -912,12 +912,6 @@ impl<T> TypeProtocol for PyRef<T> {
}
}
pub trait DictProtocol {
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef>;
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine);
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine);
}
pub trait ItemProtocol {
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult;
fn set_item<T: IntoPyObject>(
@@ -927,6 +921,22 @@ pub trait ItemProtocol {
vm: &VirtualMachine,
) -> PyResult;
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult;
fn get_item_option<T: IntoPyObject>(
&self,
key: T,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
match self.get_item(key, vm) {
Ok(value) => Ok(Some(value)),
Err(exc) => {
if objtype::isinstance(&exc, &vm.ctx.exceptions.key_error) {
Ok(None)
} else {
Err(exc)
}
}
}
}
}
impl ItemProtocol for PyObjectRef {

View File

@@ -13,9 +13,7 @@ use crate::obj::{
objstr::{self, PyString},
objtype,
};
use crate::pyobject::{
create_type, DictProtocol, IdProtocol, ItemProtocol, PyObjectRef, PyResult, TypeProtocol,
};
use crate::pyobject::{create_type, IdProtocol, ItemProtocol, PyObjectRef, PyResult, TypeProtocol};
use crate::VirtualMachine;
use num_traits::cast::ToPrimitive;
@@ -178,7 +176,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
Some(PyString { ref value }) => value.clone(),
_ => unimplemented!("map keys must be strings"),
};
dict.set_item(&key, value, self.vm);
dict.set_item(&key, value, self.vm).unwrap();
}
Ok(dict.into_object())
}

View File

@@ -3,7 +3,7 @@ use std::{env, mem};
use crate::frame::FrameRef;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
use crate::pyobject::{ItemProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
use crate::vm::VirtualMachine;
/*
@@ -139,6 +139,6 @@ settrace() -- set the global debug tracing function
"modules" => modules.clone(),
});
modules.set_item("sys", module.clone(), vm);
modules.set_item("builtins", builtins.clone(), vm);
modules.set_item("sys", module.clone(), vm).unwrap();
modules.set_item("builtins", builtins.clone(), vm).unwrap();
}

View File

@@ -30,7 +30,7 @@ use crate::obj::objtuple::PyTuple;
use crate::obj::objtype;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TryFromObject, TryIntoRef,
IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyResult, PyValue, TryFromObject, TryIntoRef,
TypeProtocol,
};
use crate::stdlib;
@@ -423,7 +423,7 @@ impl VirtualMachine {
for i in 0..n {
let arg_name = &code_object.arg_names[i];
let arg = &args.args[i];
locals.set_item(arg_name, arg.clone(), self);
locals.set_item(arg_name, arg.clone(), self)?;
}
// Pack other positional arguments in to *args:
@@ -436,7 +436,7 @@ impl VirtualMachine {
}
let vararg_value = self.ctx.new_tuple(last_args);
locals.set_item(vararg_name, vararg_value, self);
locals.set_item(vararg_name, vararg_value, self)?;
}
bytecode::Varargs::Unnamed => {
// just ignore the rest of the args
@@ -456,7 +456,7 @@ impl VirtualMachine {
let kwargs = match code_object.varkeywords {
bytecode::Varargs::Named(ref kwargs_name) => {
let d = self.ctx.new_dict();
locals.set_item(kwargs_name, d.as_object().clone(), self);
locals.set_item(kwargs_name, d.as_object().clone(), self)?;
Some(d)
}
bytecode::Varargs::Unnamed => Some(self.ctx.new_dict()),
@@ -474,9 +474,9 @@ impl VirtualMachine {
);
}
locals.set_item(&name, value, self);
locals.set_item(&name, value, self)?;
} else if let Some(d) = &kwargs {
d.set_item(&name, value, self);
d.set_item(&name, value, self)?;
} else {
return Err(
self.new_type_error(format!("Got an unexpected keyword argument '{}'", name))
@@ -520,7 +520,7 @@ impl VirtualMachine {
for (default_index, i) in (required_args..nexpected_args).enumerate() {
let arg_name = &code_object.arg_names[i];
if !locals.contains_key(arg_name, self) {
locals.set_item(arg_name, available_defaults[default_index].clone(), self);
locals.set_item(arg_name, available_defaults[default_index].clone(), self)?;
}
}
};

View File

@@ -4,7 +4,7 @@ use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
use rustpython_vm::function::PyFuncArgs;
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
use rustpython_vm::pyobject::{DictProtocol, PyObjectRef, PyResult, PyValue};
use rustpython_vm::pyobject::{ItemProtocol, PyObjectRef, PyResult, PyValue};
use rustpython_vm::VirtualMachine;
use crate::browser_module;
@@ -192,7 +192,8 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
for pair in object_entries(&Object::from(js_val)) {
let (key, val) = pair.expect("iteration over object to not fail");
let py_val = js_to_py(vm, val);
dict.set_item(&String::from(js_sys::JsString::from(key)), py_val, vm);
dict.set_item(&String::from(js_sys::JsString::from(key)), py_val, vm)
.unwrap();
}
dict.into_object()
}