From 96d37dbcd23e65a7a57819aeced9034296ef747e Mon Sep 17 00:00:00 2001 From: Fish Date: Thu, 7 Feb 2019 14:51:59 -0500 Subject: bpo-35615: Fix crashes when copying a Weak{Key,Value}Dictionary. (GH-11384) Protect dict iterations by wrapping them with _IterationGuard in the following methods: - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__() --- Lib/weakref.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'Lib/weakref.py') diff --git a/Lib/weakref.py b/Lib/weakref.py index 99de2eab74..753f07291e 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -171,10 +171,11 @@ class WeakValueDictionary(_collections_abc.MutableMapping): 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 @@ class WeakValueDictionary(_collections_abc.MutableMapping): 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 @@ class WeakKeyDictionary(_collections_abc.MutableMapping): 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 @@ class WeakKeyDictionary(_collections_abc.MutableMapping): 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): -- cgit v1.2.1