Skip to content

Commit 7b2d92f

Browse files
committed
Delete DictProtocol. impl ItemProtocol for PyDictRef.
1 parent ee9066a commit 7b2d92f

12 files changed

Lines changed: 78 additions & 59 deletions

File tree

tests/snippets/dict.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ def __getitem__(self, k):
6666
assert x['word'] == 4
6767
assert x.get('word') is None
6868

69+
assert 5 == eval("a + word", LengthDict())
70+
6971
# An object that hashes to the same value always, and compares equal if any its values match.
7072
class Hashable(object):
7173
def __init__(self, *args):

vm/src/builtins.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::obj::objtype::{self, PyClassRef};
2020
use crate::frame::Scope;
2121
use crate::function::{Args, OptionalArg, PyFuncArgs};
2222
use crate::pyobject::{
23-
DictProtocol, IdProtocol, PyIterable, PyObjectRef, PyResult, PyValue, TryFromObject,
23+
IdProtocol, ItemProtocol, PyIterable, PyObjectRef, PyResult, PyValue, TryFromObject,
2424
TypeProtocol,
2525
};
2626
use crate::vm::VirtualMachine;
@@ -804,6 +804,6 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
804804
"__call__",
805805
vec![name_arg, bases, namespace.into_object()],
806806
)?;
807-
cells.set_item("__class__", class.clone(), vm);
807+
cells.set_item("__class__", class.clone(), vm)?;
808808
Ok(class)
809809
}

vm/src/frame.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use crate::obj::objstr;
2121
use crate::obj::objtype;
2222
use crate::obj::objtype::PyClassRef;
2323
use crate::pyobject::{
24-
DictProtocol, IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
25-
TryFromObject, TypeProtocol,
24+
IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
25+
TypeProtocol,
2626
};
2727
use crate::vm::VirtualMachine;
2828
use itertools::Itertools;
@@ -133,12 +133,12 @@ pub trait NameProtocol {
133133
impl NameProtocol for Scope {
134134
fn load_name(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
135135
for dict in self.locals.iter() {
136-
if let Some(value) = dict.get_item(name, vm) {
136+
if let Some(value) = dict.get_item_option(name, vm).unwrap() {
137137
return Some(value);
138138
}
139139
}
140140

141-
if let Some(value) = self.globals.get_item(name, vm) {
141+
if let Some(value) = self.globals.get_item_option(name, vm).unwrap() {
142142
return Some(value);
143143
}
144144

@@ -147,19 +147,19 @@ impl NameProtocol for Scope {
147147

148148
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
149149
for dict in self.locals.iter().skip(1) {
150-
if let Some(value) = dict.get_item(name, vm) {
150+
if let Some(value) = dict.get_item_option(name, vm).unwrap() {
151151
return Some(value);
152152
}
153153
}
154154
None
155155
}
156156

157157
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
158-
self.get_locals().set_item(key, value, vm)
158+
self.get_locals().set_item(key, value, vm).unwrap();
159159
}
160160

161161
fn delete_name(&self, vm: &VirtualMachine, key: &str) {
162-
self.get_locals().del_item(key, vm)
162+
self.get_locals().del_item(key, vm).unwrap();
163163
}
164164
}
165165

@@ -394,12 +394,12 @@ impl Frame {
394394
obj.downcast().expect("Need a dictionary to build a map.");
395395
let dict_elements = dict.get_key_value_pairs();
396396
for (key, value) in dict_elements.iter() {
397-
map_obj.set_item(key.clone(), value.clone(), vm);
397+
map_obj.set_item(key.clone(), value.clone(), vm).unwrap();
398398
}
399399
}
400400
} else {
401401
for (key, value) in self.pop_multiple(2 * size).into_iter().tuples() {
402-
map_obj.set_item(key, value, vm)
402+
map_obj.set_item(key, value, vm).unwrap();
403403
}
404404
}
405405

vm/src/import.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::path::PathBuf;
88
use crate::compile;
99
use crate::frame::Scope;
1010
use crate::obj::{objsequence, objstr};
11-
use crate::pyobject::{DictProtocol, ItemProtocol, PyResult};
11+
use crate::pyobject::{ItemProtocol, PyResult};
1212
use crate::util;
1313
use crate::vm::VirtualMachine;
1414

@@ -39,7 +39,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
3939
// trace!("Code object: {:?}", code_obj);
4040

4141
let attrs = vm.ctx.new_dict();
42-
attrs.set_item("__name__", vm.new_str(module.to_string()), vm);
42+
attrs.set_item("__name__", vm.new_str(module.to_string()), vm)?;
4343
vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
4444
Ok(vm.ctx.new_module(module, attrs))
4545
}

vm/src/obj/objdict.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use std::fmt;
33

44
use crate::function::{KwArgs, OptionalArg};
55
use crate::pyobject::{
6-
DictProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyContext, PyObjectRef, PyRef,
7-
PyResult, PyValue,
6+
IntoPyObject, ItemProtocol, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
87
};
98
use crate::vm::{ReprGuard, VirtualMachine};
109

@@ -174,8 +173,8 @@ impl PyDictRef {
174173
self.entries.borrow().get_items()
175174
}
176175

177-
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
178-
self.set_item(key, value, vm)
176+
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
177+
self.entries.borrow_mut().insert(vm, &key, value)
179178
}
180179

181180
fn getitem(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -223,21 +222,26 @@ impl PyDictRef {
223222
}
224223
}
225224

226-
impl DictProtocol for PyDictRef {
227-
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
228-
let key = key.into_pyobject(vm).unwrap();
229-
self.entries.borrow().get(vm, &key).unwrap()
225+
impl ItemProtocol for PyDictRef {
226+
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
227+
vm.call_method(self.as_object(), "__getitem__", key.into_pyobject(vm)?)
230228
}
231229

232-
// Item set/get:
233-
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
234-
let key = key.into_pyobject(vm).unwrap();
235-
self.entries.borrow_mut().insert(vm, &key, value).unwrap()
230+
fn set_item<T: IntoPyObject>(
231+
&self,
232+
key: T,
233+
value: PyObjectRef,
234+
vm: &VirtualMachine,
235+
) -> PyResult {
236+
vm.call_method(
237+
self.as_object(),
238+
"__setitem__",
239+
vec![key.into_pyobject(vm)?, value],
240+
)
236241
}
237242

238-
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) {
239-
let key = key.into_pyobject(vm).unwrap();
240-
self.entries.borrow_mut().delete(vm, &key).unwrap();
243+
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
244+
vm.call_method(self.as_object(), "__delitem__", key.into_pyobject(vm)?)
241245
}
242246
}
243247

vm/src/obj/objobject.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::function::PyFuncArgs;
66
use crate::obj::objproperty::PropertyBuilder;
77
use crate::obj::objtype::PyClassRef;
88
use crate::pyobject::{
9-
DictProtocol, IdProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
9+
IdProtocol, ItemProtocol, PyAttributes, PyContext, PyObject, PyObjectRef, PyResult, PyValue,
1010
TryFromObject, TypeProtocol,
1111
};
1212
use crate::vm::VirtualMachine;
@@ -77,7 +77,7 @@ fn object_setattr(
7777
}
7878

7979
if let Some(ref dict) = obj.clone().dict {
80-
dict.set_item(attr_name, value, vm);
80+
dict.set_item(attr_name, value, vm)?;
8181
Ok(())
8282
} else {
8383
Err(vm.new_attribute_error(format!(
@@ -98,7 +98,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
9898
}
9999

100100
if let Some(ref dict) = obj.dict {
101-
dict.del_item(attr_name, vm);
101+
dict.del_item(attr_name, vm)?;
102102
Ok(())
103103
} else {
104104
Err(vm.new_attribute_error(format!(
@@ -208,7 +208,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
208208
}
209209
}
210210

211-
if let Some(obj_attr) = object_getattr(&obj, &name, &vm) {
211+
if let Some(obj_attr) = object_getattr(&obj, &name, &vm)? {
212212
Ok(obj_attr)
213213
} else if let Some(attr) = objtype::class_get_attr(&cls, &name) {
214214
vm.call_get_descriptor(attr, obj)
@@ -219,11 +219,15 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
219219
}
220220
}
221221

222-
fn object_getattr(obj: &PyObjectRef, attr_name: &str, vm: &VirtualMachine) -> Option<PyObjectRef> {
222+
fn object_getattr(
223+
obj: &PyObjectRef,
224+
attr_name: &str,
225+
vm: &VirtualMachine,
226+
) -> PyResult<Option<PyObjectRef>> {
223227
if let Some(ref dict) = obj.dict {
224-
dict.get_item(attr_name, vm)
228+
dict.get_item_option(attr_name, vm)
225229
} else {
226-
None
230+
Ok(None)
227231
}
228232
}
229233

vm/src/obj/objsuper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::obj::objfunction::PyMethod;
1212
use crate::obj::objstr;
1313
use crate::obj::objtype::{PyClass, PyClassRef};
1414
use crate::pyobject::{
15-
DictProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
15+
ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
1616
};
1717
use crate::vm::VirtualMachine;
1818

@@ -124,7 +124,7 @@ fn super_new(
124124
} else {
125125
let frame = vm.current_frame().expect("no current frame for super()");
126126
if let Some(first_arg) = frame.code.arg_names.get(0) {
127-
match vm.get_locals().get_item(first_arg, vm) {
127+
match vm.get_locals().get_item_option(first_arg, vm)? {
128128
Some(obj) => obj.clone(),
129129
_ => {
130130
return Err(vm

vm/src/pyobject.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -912,12 +912,6 @@ impl<T> TypeProtocol for PyRef<T> {
912912
}
913913
}
914914

915-
pub trait DictProtocol {
916-
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef>;
917-
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine);
918-
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine);
919-
}
920-
921915
pub trait ItemProtocol {
922916
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult;
923917
fn set_item<T: IntoPyObject>(
@@ -927,6 +921,22 @@ pub trait ItemProtocol {
927921
vm: &VirtualMachine,
928922
) -> PyResult;
929923
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult;
924+
fn get_item_option<T: IntoPyObject>(
925+
&self,
926+
key: T,
927+
vm: &VirtualMachine,
928+
) -> PyResult<Option<PyObjectRef>> {
929+
match self.get_item(key, vm) {
930+
Ok(value) => Ok(Some(value)),
931+
Err(exc) => {
932+
if objtype::isinstance(&exc, &vm.ctx.exceptions.key_error) {
933+
Ok(None)
934+
} else {
935+
Err(exc)
936+
}
937+
}
938+
}
939+
}
930940
}
931941

932942
impl ItemProtocol for PyObjectRef {

vm/src/stdlib/json.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use crate::obj::{
1313
objstr::{self, PyString},
1414
objtype,
1515
};
16-
use crate::pyobject::{
17-
create_type, DictProtocol, IdProtocol, ItemProtocol, PyObjectRef, PyResult, TypeProtocol,
18-
};
16+
use crate::pyobject::{create_type, IdProtocol, ItemProtocol, PyObjectRef, PyResult, TypeProtocol};
1917
use crate::VirtualMachine;
2018
use num_traits::cast::ToPrimitive;
2119

@@ -178,7 +176,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
178176
Some(PyString { ref value }) => value.clone(),
179177
_ => unimplemented!("map keys must be strings"),
180178
};
181-
dict.set_item(&key, value, self.vm);
179+
dict.set_item(&key, value, self.vm).unwrap();
182180
}
183181
Ok(dict.into_object())
184182
}

vm/src/sysmodule.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{env, mem};
33

44
use crate::frame::FrameRef;
55
use crate::function::{OptionalArg, PyFuncArgs};
6-
use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
6+
use crate::pyobject::{ItemProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
77
use crate::vm::VirtualMachine;
88

99
/*
@@ -139,6 +139,6 @@ settrace() -- set the global debug tracing function
139139
"modules" => modules.clone(),
140140
});
141141

142-
modules.set_item("sys", module.clone(), vm);
143-
modules.set_item("builtins", builtins.clone(), vm);
142+
modules.set_item("sys", module.clone(), vm).unwrap();
143+
modules.set_item("builtins", builtins.clone(), vm).unwrap();
144144
}

0 commit comments

Comments
 (0)