Skip to content

Commit 7d7e9c8

Browse files
authored
Merge pull request #3585 from dieterplex/fixtestuserdict
Fix dict.fromkeys to return correct type
2 parents 7466d17 + 3037508 commit 7d7e9c8

2 files changed

Lines changed: 18 additions & 11 deletions

File tree

‎Lib/test/test_dict.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,6 @@ def __next__(self):
212212

213213
self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
214214

215-
# TODO: RUSTPYTHON
216-
@unittest.expectedFailure
217215
def test_fromkeys(self):
218216
self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
219217
d = {}

‎vm/src/builtins/dict.rs‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{
22
set::PySetInner, IterStatus, PositionIterInternal, PyBaseExceptionRef, PyGenericAlias, PySet,
3-
PyStrRef, PyTupleRef, PyTypeRef,
3+
PyStrRef, PyTupleRef, PyType, PyTypeRef,
44
};
55
use crate::{
66
builtins::{iter::builtins_iter, PyTuple},
@@ -9,8 +9,8 @@ use crate::{
99
function::{ArgIterable, FuncArgs, IntoPyObject, KwArgs, OptionalArg},
1010
protocol::{PyIterIter, PyIterReturn, PyMappingMethods, PySequenceMethods},
1111
types::{
12-
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
13-
Iterable, PyComparisonOp, Unconstructible, Unhashable,
12+
AsMapping, AsSequence, Callable, Comparable, Constructor, Hashable, IterNext,
13+
IterNextIterable, Iterable, PyComparisonOp, Unconstructible, Unhashable,
1414
},
1515
vm::{ReprGuard, VirtualMachine},
1616
IdProtocol,
@@ -150,14 +150,23 @@ impl PyDict {
150150
iterable: ArgIterable,
151151
value: OptionalArg<PyObjectRef>,
152152
vm: &VirtualMachine,
153-
) -> PyResult<PyRef<Self>> {
154-
let dict = DictContentType::default();
153+
) -> PyResult {
155154
let value = value.unwrap_or_none(vm);
156-
for elem in iterable.iter(vm)? {
157-
let elem = elem?;
158-
dict.insert(vm, elem, value.clone())?;
155+
let d = PyType::call(&class, ().into(), vm)?;
156+
match d.downcast_exact::<PyDict>(vm) {
157+
Ok(pydict) => {
158+
for key in iterable.iter(vm)? {
159+
pydict.setitem(key?, value.clone(), vm)?;
160+
}
161+
Ok(pydict.into_pyobject(vm))
162+
}
163+
Err(pyobj) => {
164+
for key in iterable.iter(vm)? {
165+
pyobj.set_item(key?, value.clone(), vm)?;
166+
}
167+
Ok(pyobj)
168+
}
159169
}
160-
PyDict { entries: dict }.into_ref_with_type(vm, class)
161170
}
162171

163172
#[pymethod(magic)]

0 commit comments

Comments
 (0)