From 746fe0fae5442403c64be34b87609601166e97c8 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 28 Sep 2001 19:01:26 +0000 Subject: [PATCH] Clean up circular references in the Weak*Dictionary classes; this avoids depending on the cycle detector code in the library implementation. This is a *slightly* different patch than SF patch #417795, but takes the same approach. (This version avoids calling the __len__() method of the dict in the remove() functions.) This closes SF patch #417795. --- Lib/weakref.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Lib/weakref.py b/Lib/weakref.py index c71d04b8535..0cf6bf9cc32 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -51,9 +51,7 @@ class WeakValueDictionary(UserDict.UserDict): return "" % id(self) def __setitem__(self, key, value): - def remove(o, data=self.data, key=key): - del data[key] - self.data[key] = ref(value, remove) + self.data[key] = ref(value, self.__makeremove(key)) def copy(self): new = WeakValueDictionary() @@ -105,9 +103,7 @@ class WeakValueDictionary(UserDict.UserDict): try: wr = self.data[key] except KeyError: - def remove(o, data=self.data, key=key): - del data[key] - self.data[key] = ref(default, remove) + self.data[key] = ref(default, self.__makeremove(key)) return default else: return wr() @@ -115,9 +111,7 @@ class WeakValueDictionary(UserDict.UserDict): def update(self, dict): d = self.data for key, o in dict.items(): - def remove(o, data=d, key=key): - del data[key] - d[key] = ref(o, remove) + d[key] = ref(o, self.__makeremove(key)) def values(self): L = [] @@ -127,6 +121,13 @@ class WeakValueDictionary(UserDict.UserDict): L.append(o) return L + def __makeremove(self, key): + def remove(o, selfref=ref(self), key=key): + self = selfref() + if self is not None: + del self.data[key] + return remove + class WeakKeyDictionary(UserDict.UserDict): """ Mapping class that references keys weakly. @@ -142,8 +143,10 @@ class WeakKeyDictionary(UserDict.UserDict): def __init__(self, dict=None): self.data = {} if dict is not None: self.update(dict) - def remove(k, data=self.data): - del data[k] + def remove(k, selfref=ref(self)): + self = selfref() + if self is not None: + del self.data[k] self._remove = remove def __delitem__(self, key):