Skip to content

Commit 8535ba9

Browse files
Merge pull request RustPython#786 from RustPython/dict_cleanup
Dict cleanup
2 parents 59d8612 + f354f4c commit 8535ba9

File tree

6 files changed

+39
-47
lines changed

6 files changed

+39
-47
lines changed

vm/src/frame.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::function::PyFuncArgs;
1212
use crate::obj::objbool;
1313
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
1414
use crate::obj::objcode::PyCodeRef;
15-
use crate::obj::objdict::{self, PyDictRef};
15+
use crate::obj::objdict::PyDictRef;
1616
use crate::obj::objint::PyInt;
1717
use crate::obj::objiter;
1818
use crate::obj::objlist;
@@ -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, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
25-
TypeProtocol,
24+
DictProtocol, IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
25+
TryFromObject, TypeProtocol,
2626
};
2727
use crate::vm::VirtualMachine;
2828

@@ -390,7 +390,9 @@ impl Frame {
390390
let obj = self.pop_value();
391391
if *unpack {
392392
// Take all key-value pairs from the dict:
393-
let dict_elements = objdict::get_key_value_pairs(&obj);
393+
let dict: PyDictRef =
394+
obj.downcast().expect("Need a dictionary to build a map.");
395+
let dict_elements = dict.get_key_value_pairs();
394396
for (key, value) in dict_elements.iter() {
395397
map_obj.set_item(key.clone(), value.clone(), vm);
396398
}
@@ -612,8 +614,9 @@ impl Frame {
612614
}
613615
bytecode::CallType::Ex(has_kwargs) => {
614616
let kwargs = if *has_kwargs {
615-
let kw_dict = self.pop_value();
616-
let dict_elements = objdict::get_key_value_pairs(&kw_dict).clone();
617+
let kw_dict: PyDictRef =
618+
self.pop_value().downcast().expect("Kwargs must be a dict.");
619+
let dict_elements = kw_dict.get_key_value_pairs();
617620
dict_elements
618621
.into_iter()
619622
.map(|elem| (objstr::get_value(&elem.0), elem.1))
@@ -987,22 +990,18 @@ impl Frame {
987990
}
988991
}
989992

990-
fn subscript(&self, vm: &VirtualMachine, a: PyObjectRef, b: PyObjectRef) -> PyResult {
991-
vm.call_method(&a, "__getitem__", vec![b])
992-
}
993-
994993
fn execute_store_subscript(&self, vm: &VirtualMachine) -> FrameResult {
995994
let idx = self.pop_value();
996995
let obj = self.pop_value();
997996
let value = self.pop_value();
998-
vm.call_method(&obj, "__setitem__", vec![idx, value])?;
997+
obj.set_item(idx, value, vm)?;
999998
Ok(None)
1000999
}
10011000

10021001
fn execute_delete_subscript(&self, vm: &VirtualMachine) -> FrameResult {
10031002
let idx = self.pop_value();
10041003
let obj = self.pop_value();
1005-
vm.call_method(&obj, "__delitem__", vec![idx])?;
1004+
obj.del_item(idx, vm)?;
10061005
Ok(None)
10071006
}
10081007

@@ -1037,7 +1036,7 @@ impl Frame {
10371036
bytecode::BinaryOperator::FloorDivide => vm._floordiv(a_ref, b_ref),
10381037
// TODO: Subscript should probably have its own op
10391038
bytecode::BinaryOperator::Subscript if inplace => unreachable!(),
1040-
bytecode::BinaryOperator::Subscript => self.subscript(vm, a_ref, b_ref),
1039+
bytecode::BinaryOperator::Subscript => a_ref.get_item(b_ref, vm),
10411040
bytecode::BinaryOperator::Modulo if inplace => vm._imod(a_ref, b_ref),
10421041
bytecode::BinaryOperator::Modulo => vm._mod(a_ref, b_ref),
10431042
bytecode::BinaryOperator::Lshift if inplace => vm._ilshift(a_ref, b_ref),

vm/src/obj/objdict.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use crate::dictdatatype;
1313
use super::objiter;
1414
use super::objlist::PyListIterator;
1515
use super::objstr;
16-
use super::objtype;
1716
use crate::obj::objtype::PyClassRef;
1817

1918
pub type DictContentType = dictdatatype::Dict;
@@ -38,14 +37,6 @@ impl PyValue for PyDict {
3837
}
3938
}
4039

41-
pub fn get_key_value_pairs(dict: &PyObjectRef) -> Vec<(PyObjectRef, PyObjectRef)> {
42-
dict.payload::<PyDict>()
43-
.unwrap()
44-
.entries
45-
.borrow()
46-
.get_items()
47-
}
48-
4940
// Python dict methods:
5041
impl PyDictRef {
5142
fn new(
@@ -56,9 +47,10 @@ impl PyDictRef {
5647
) -> PyResult<PyDictRef> {
5748
let dict = vm.ctx.new_dict();
5849
if let OptionalArg::Present(dict_obj) = dict_obj {
59-
if objtype::isinstance(&dict_obj, &vm.ctx.dict_type()) {
60-
for (needle, value) in get_key_value_pairs(&dict_obj) {
61-
dict.set_item(needle, value, vm);
50+
let dicted: PyResult<PyDictRef> = dict_obj.clone().downcast();
51+
if let Ok(dict_obj) = dicted {
52+
for (key, value) in dict_obj.get_key_value_pairs() {
53+
dict.set_item(key, value, vm);
6254
}
6355
} else {
6456
let iter = objiter::get_iter(vm, &dict_obj)?;
@@ -71,18 +63,17 @@ impl PyDictRef {
7163
None => break,
7264
};
7365
let elem_iter = objiter::get_iter(vm, &element)?;
74-
let needle =
75-
objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
66+
let key = objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
7667
let value = objiter::get_next_object(vm, &elem_iter)?.ok_or_else(|| err(vm))?;
7768
if objiter::get_next_object(vm, &elem_iter)?.is_some() {
7869
return Err(err(vm));
7970
}
80-
dict.set_item(needle, value, vm);
71+
dict.set_item(key, value, vm);
8172
}
8273
}
8374
}
84-
for (needle, value) in kwargs.into_iter() {
85-
dict.set_item(vm.new_str(needle), value, vm);
75+
for (key, value) in kwargs.into_iter() {
76+
dict.set_item(vm.new_str(key), value, vm);
8677
}
8778
Ok(dict)
8879
}
@@ -97,9 +88,8 @@ impl PyDictRef {
9788

9889
fn repr(self, vm: &VirtualMachine) -> PyResult {
9990
let s = if let Some(_guard) = ReprGuard::enter(self.as_object()) {
100-
let elements = get_key_value_pairs(self.as_object());
10191
let mut str_parts = vec![];
102-
for (key, value) in elements {
92+
for (key, value) in self.get_key_value_pairs() {
10393
let key_repr = vm.to_repr(&key)?;
10494
let value_repr = vm.to_repr(&value)?;
10595
str_parts.push(format!("{}: {}", key_repr.value, value_repr.value));
@@ -176,8 +166,12 @@ impl PyDictRef {
176166
}
177167
}
178168

179-
fn setitem(self, needle: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
180-
self.set_item(needle, value, vm)
169+
pub fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
170+
self.entries.borrow().get_items()
171+
}
172+
173+
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
174+
self.set_item(key, value, vm)
181175
}
182176

183177
fn getitem(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -212,23 +206,19 @@ impl PyDictRef {
212206
fn hash(self, vm: &VirtualMachine) -> PyResult {
213207
Err(vm.new_type_error("unhashable type".to_string()))
214208
}
215-
}
216209

217-
impl DictProtocol for PyDictRef {
218-
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
210+
pub fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
219211
let key = key.into_pyobject(vm).unwrap();
220212
self.entries.borrow().contains(vm, &key).unwrap()
221213
}
214+
}
222215

216+
impl DictProtocol for PyDictRef {
223217
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
224218
let key = key.into_pyobject(vm).unwrap();
225219
self.entries.borrow().get(vm, &key).ok()
226220
}
227221

228-
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
229-
get_key_value_pairs(self.as_object())
230-
}
231-
232222
// Item set/get:
233223
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
234224
let key = key.into_pyobject(vm).unwrap();

vm/src/obj/objmodule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::obj::objtype::PyClassRef;
2-
use crate::pyobject::{DictProtocol, PyContext, PyRef, PyResult, PyValue};
2+
use crate::pyobject::{PyContext, PyRef, PyResult, PyValue};
33
use crate::vm::VirtualMachine;
44

55
#[derive(Debug)]

vm/src/pyobject.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -913,9 +913,7 @@ impl<T> TypeProtocol for PyRef<T> {
913913
}
914914

915915
pub trait DictProtocol {
916-
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool;
917916
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef>;
918-
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)>;
919917
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine);
920918
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine);
921919
}

vm/src/stdlib/json.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use serde_json;
77

88
use crate::function::PyFuncArgs;
99
use crate::obj::{
10-
objbool, objdict, objfloat, objint, objsequence,
10+
objbool,
11+
objdict::PyDictRef,
12+
objfloat, objint, objsequence,
1113
objstr::{self, PyString},
1214
objtype,
1315
};
@@ -63,7 +65,8 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
6365
let elements = objsequence::get_elements(self.pyobject);
6466
serialize_seq_elements(serializer, &elements)
6567
} else if objtype::isinstance(self.pyobject, &self.vm.ctx.dict_type()) {
66-
let pairs = objdict::get_key_value_pairs(self.pyobject);
68+
let dict: PyDictRef = self.pyobject.clone().downcast().unwrap();
69+
let pairs = dict.get_key_value_pairs();
6770
let mut map = serializer.serialize_map(Some(pairs.len()))?;
6871
for (key, e) in pairs.iter() {
6972
map.serialize_entry(&self.clone_with_object(key), &self.clone_with_object(&e))?;

wasm/lib/src/browser_module.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use wasm_bindgen_futures::{future_to_promise, JsFuture};
77

88
use rustpython_vm::function::{OptionalArg, PyFuncArgs};
99
use rustpython_vm::obj::{
10+
objdict::PyDictRef,
1011
objfunction::PyFunction,
1112
objint,
1213
objstr::{self, PyStringRef},
@@ -72,7 +73,8 @@ fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
7273

7374
if let Some(headers) = headers {
7475
let h = request.headers();
75-
for (key, value) in rustpython_vm::obj::objdict::get_key_value_pairs(&headers) {
76+
let headers: PyDictRef = headers.downcast().unwrap();
77+
for (key, value) in headers.get_key_value_pairs() {
7678
let key = &vm.to_str(&key)?.value;
7779
let value = &vm.to_str(&value)?.value;
7880
h.set(key, value)

0 commit comments

Comments
 (0)