bpo-35615: Fix crashes when copying a Weak{Key,Value}Dictionary. (GH-11384) (GH-11785)
Protect dict iterations by wrapping them with _IterationGuard in the
following methods:
- WeakValueDictionary.copy()
- WeakValueDictionary.__deepcopy__()
- WeakKeyDictionary.copy()
- WeakKeyDictionary.__deepcopy__()
(cherry picked from commit 96d37dbcd23e65a7a57819aeced9034296ef747e)
Co-authored-by: Fish <ltfish@users.noreply.github.com>
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 99de2ea..753f072 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -171,10 +171,11 @@
if self._pending_removals:
self._commit_removals()
new = WeakValueDictionary()
- for key, wr in self.data.items():
- o = wr()
- if o is not None:
- new[key] = o
+ with _IterationGuard(self):
+ for key, wr in self.data.items():
+ o = wr()
+ if o is not None:
+ new[key] = o
return new
__copy__ = copy
@@ -184,10 +185,11 @@
if self._pending_removals:
self._commit_removals()
new = self.__class__()
- for key, wr in self.data.items():
- o = wr()
- if o is not None:
- new[deepcopy(key, memo)] = o
+ with _IterationGuard(self):
+ for key, wr in self.data.items():
+ o = wr()
+ if o is not None:
+ new[deepcopy(key, memo)] = o
return new
def get(self, key, default=None):
@@ -408,10 +410,11 @@
def copy(self):
new = WeakKeyDictionary()
- for key, value in self.data.items():
- o = key()
- if o is not None:
- new[o] = value
+ with _IterationGuard(self):
+ for key, value in self.data.items():
+ o = key()
+ if o is not None:
+ new[o] = value
return new
__copy__ = copy
@@ -419,10 +422,11 @@
def __deepcopy__(self, memo):
from copy import deepcopy
new = self.__class__()
- for key, value in self.data.items():
- o = key()
- if o is not None:
- new[o] = deepcopy(value, memo)
+ with _IterationGuard(self):
+ for key, value in self.data.items():
+ o = key()
+ if o is not None:
+ new[o] = deepcopy(value, memo)
return new
def get(self, key, default=None):