From 9addff5ba956f1f05c8b1d19167d6e930b0c4120 Mon Sep 17 00:00:00 2001 From: eldpswp99 Date: Thu, 26 Aug 2021 21:02:45 +0900 Subject: [PATCH] add mutation check in dict.merge --- Lib/test/test_dict.py | 2 -- vm/src/builtins/dict.rs | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 718d896a9..2ecb91d44 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1226,8 +1226,6 @@ class DictTest(unittest.TestCase): d.popitem() self.check_reentrant_insertion(mutate) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_merge_and_mutate(self): class X: def __hash__(self): diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 3ea13a4d6..b9c8e18d4 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -77,9 +77,13 @@ impl PyDict { if let OptionalArg::Present(dict_obj) = dict_obj { let dicted: Result = dict_obj.clone().downcast_exact(vm); if let Ok(dict_obj) = dicted { - for (key, value) in dict_obj { + let dict_size = &dict_obj.size(); + for (key, value) in &dict_obj { dict.insert(vm, key, value)?; } + if dict_obj.entries.has_changed_size(dict_size) { + return Err(vm.new_runtime_error("dict mutated during update".to_owned())); + } } else if let Some(keys) = vm.get_method(dict_obj.clone(), "keys") { let keys = iterator::get_iter(vm, vm.invoke(&keys?, ())?)?; while let Some(key) = iterator::get_next_object(vm, &keys)? {