Skip to content

Commit 1c43a6b

Browse files
committed
Add dict.setdefault.
1 parent ceac014 commit 1c43a6b

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

tests/snippets/dict.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,11 @@ def __eq__(self, other):
180180
with assertRaises(KeyError):
181181
x.popitem()
182182
assert x == {}
183+
184+
x = {'a': 4}
185+
assert 4 == x.setdefault('a', 0)
186+
assert x['a'] == 4
187+
assert 0 == x.setdefault('b', 0)
188+
assert x['b'] == 0
189+
assert None == x.setdefault('c')
190+
assert x['c'] is None

vm/src/obj/objdict.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,26 @@ impl PyDictRef {
213213
}
214214
}
215215

216+
fn setdefault(
217+
self,
218+
key: PyObjectRef,
219+
default: OptionalArg<PyObjectRef>,
220+
vm: &VirtualMachine,
221+
) -> PyResult {
222+
let mut entries = self.entries.borrow_mut();
223+
match entries.get(vm, &key)? {
224+
Some(value) => Ok(value),
225+
None => {
226+
let set_value = match default {
227+
OptionalArg::Present(value) => value,
228+
OptionalArg::Missing => vm.ctx.none(),
229+
};
230+
entries.insert(vm, &key, set_value.clone())?;
231+
Ok(set_value)
232+
}
233+
}
234+
}
235+
216236
fn copy(self, _vm: &VirtualMachine) -> PyDict {
217237
PyDict {
218238
entries: self.entries.clone(),
@@ -473,6 +493,7 @@ pub fn init(context: &PyContext) {
473493
"items" => context.new_rustfunc(PyDictRef::items),
474494
"keys" => context.new_rustfunc(PyDictRef::keys),
475495
"get" => context.new_rustfunc(PyDictRef::get),
496+
"setdefault" => context.new_rustfunc(PyDictRef::setdefault),
476497
"copy" => context.new_rustfunc(PyDictRef::copy),
477498
"update" => context.new_rustfunc(PyDictRef::update),
478499
"pop" => context.new_rustfunc(PyDictRef::pop),

0 commit comments

Comments
 (0)