diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index c3a9805988f..9cbe6dc641e 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -6791,7 +6791,6 @@ def _test_dict(cls, obj): obj.clear() case.assertEqual(len(obj), 0) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_dict(self): o = self.manager.dict() o['foo'] = 5 diff --git a/crates/vm/src/builtins/dict.rs b/crates/vm/src/builtins/dict.rs index d14536eef53..af74a259157 100644 --- a/crates/vm/src/builtins/dict.rs +++ b/crates/vm/src/builtins/dict.rs @@ -7,11 +7,7 @@ use crate::object::{Traverse, TraverseFn}; use crate::{ AsObject, Context, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, TryFromObject, atomic_func, - builtins::{ - PyTuple, - iter::{builtins_iter, builtins_reversed}, - type_::PyAttributes, - }, + builtins::{PyTuple, iter::builtins_iter, type_::PyAttributes}, class::{PyClassDef, PyClassImpl}, common::ascii, dict_inner::{self, DictKey}, @@ -1118,10 +1114,17 @@ macro_rules! dict_view { let iter = builtins_iter(vm); let internal = self.internal.lock(); let entries = match &internal.status { - IterStatus::Active(dict) => dict - .into_iter() - .map(|(key, value)| ($result_fn)(vm, key, value)) - .collect::>(), + IterStatus::Active(dict) => { + let mut position = internal.position; + let mut entries = Vec::new(); + while let Some((next_position, key, value)) = + dict.entries.next_entry(position) + { + entries.push(($result_fn)(vm, key, value)); + position = next_position; + } + entries + } IterStatus::Exhausted => vec![], }; vm.new_tuple((iter, (vm.ctx.new_list(entries),))) @@ -1184,14 +1187,23 @@ macro_rules! dict_view { #[pymethod] fn __reduce__(&self, vm: &VirtualMachine) -> PyTupleRef { - let iter = builtins_reversed(vm); + let iter = builtins_iter(vm); let internal = self.internal.lock(); - // TODO: entries must be reversed too let entries = match &internal.status { - IterStatus::Active(dict) => dict - .into_iter() - .map(|(key, value)| ($result_fn)(vm, key, value)) - .collect::>(), + IterStatus::Active(dict) => { + let mut position = internal.position; + let mut entries = Vec::new(); + while let Some((found_index, key, value)) = + dict.entries.prev_entry(position) + { + entries.push(($result_fn)(vm, key, value)); + if found_index == 0 { + break; + } + position = found_index - 1; + } + entries + } IterStatus::Exhausted => vec![], }; vm.new_tuple((iter, (vm.ctx.new_list(entries),))) @@ -1218,11 +1230,11 @@ macro_rules! dict_view { ); } match dict.entries.prev_entry(internal.position) { - Some((position, key, value)) => { - if internal.position == position { + Some((found_index, key, value)) => { + if found_index == 0 { internal.status = IterStatus::Exhausted; } else { - internal.position = position; + internal.position = found_index - 1; } PyIterReturn::Return(($result_fn)(vm, key, value)) } diff --git a/crates/vm/src/dict_inner.rs b/crates/vm/src/dict_inner.rs index 3b5f5617f02..cc26383d9b8 100644 --- a/crates/vm/src/dict_inner.rs +++ b/crates/vm/src/dict_inner.rs @@ -861,10 +861,13 @@ impl Dict { let inner = self.read(); loop { let entry = inner.entries.get(position)?; - position = position.saturating_sub(1); if let Some(entry) = entry { break Some((position, entry.key.clone(), entry.value.clone())); } + if position == 0 { + break None; + } + position -= 1; } }