From 69c00da17c30f9932845c8119013b7d82aa672e7 Mon Sep 17 00:00:00 2001 From: rozyczko Date: Fri, 19 Sep 2025 08:39:54 +0200 Subject: [PATCH 1/2] try to copy the dict when it gets changed during garbage collection --- src/easyscience/global_object/map.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/easyscience/global_object/map.py b/src/easyscience/global_object/map.py index 53a3aac4..5cd89eaa 100644 --- a/src/easyscience/global_object/map.py +++ b/src/easyscience/global_object/map.py @@ -76,7 +76,19 @@ def __init__(self): def vertices(self) -> List[str]: """returns the vertices of a map""" - return list(self._store.keys()) + # Create a copy to avoid "dictionary changed size during iteration" errors + # This can happen when objects are garbage collected during iteration + try: + return list(self._store.keys()) + except RuntimeError: + # If we hit a concurrent modification, create a safe copy + # by iterating through items and collecting valid keys + valid_keys = [] + items = list(self._store.data.items()) if hasattr(self._store, 'data') else [] + for key, ref in items: + if ref() is not None: # Only include keys with valid references + valid_keys.append(key) + return valid_keys def edges(self): """returns the edges of a map""" From 8ff1cc61a29b6ac847c8c8e14bf4e0d6d6c73848 Mon Sep 17 00:00:00 2001 From: rozyczko Date: Fri, 19 Sep 2025 13:43:47 +0200 Subject: [PATCH 2/2] removed unnecessary conditional + added more comments --- src/easyscience/global_object/map.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/easyscience/global_object/map.py b/src/easyscience/global_object/map.py index 5cd89eaa..36fd2a1c 100644 --- a/src/easyscience/global_object/map.py +++ b/src/easyscience/global_object/map.py @@ -84,9 +84,13 @@ def vertices(self) -> List[str]: # If we hit a concurrent modification, create a safe copy # by iterating through items and collecting valid keys valid_keys = [] - items = list(self._store.data.items()) if hasattr(self._store, 'data') else [] + # Query all weak references to avoid modification during iteration + # WeakValueDictionary does not support items() directly, so we access the underlying data + items = list(self._store.data.items()) for key, ref in items: - if ref() is not None: # Only include keys with valid references + # Instantiating the weak reference to see if the object is still alive + # This test does not modify the dictionary + if ref() is not None: valid_keys.append(key) return valid_keys