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.
This commit is contained in:
Fred Drake 2001-09-28 19:01:26 +00:00
parent 43b9a086bf
commit 746fe0fae5
1 changed files with 14 additions and 11 deletions

View File

@ -51,9 +51,7 @@ class WeakValueDictionary(UserDict.UserDict):
return "<WeakValueDictionary at %s>" % id(self) return "<WeakValueDictionary at %s>" % id(self)
def __setitem__(self, key, value): def __setitem__(self, key, value):
def remove(o, data=self.data, key=key): self.data[key] = ref(value, self.__makeremove(key))
del data[key]
self.data[key] = ref(value, remove)
def copy(self): def copy(self):
new = WeakValueDictionary() new = WeakValueDictionary()
@ -105,9 +103,7 @@ class WeakValueDictionary(UserDict.UserDict):
try: try:
wr = self.data[key] wr = self.data[key]
except KeyError: except KeyError:
def remove(o, data=self.data, key=key): self.data[key] = ref(default, self.__makeremove(key))
del data[key]
self.data[key] = ref(default, remove)
return default return default
else: else:
return wr() return wr()
@ -115,9 +111,7 @@ class WeakValueDictionary(UserDict.UserDict):
def update(self, dict): def update(self, dict):
d = self.data d = self.data
for key, o in dict.items(): for key, o in dict.items():
def remove(o, data=d, key=key): d[key] = ref(o, self.__makeremove(key))
del data[key]
d[key] = ref(o, remove)
def values(self): def values(self):
L = [] L = []
@ -127,6 +121,13 @@ class WeakValueDictionary(UserDict.UserDict):
L.append(o) L.append(o)
return L 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): class WeakKeyDictionary(UserDict.UserDict):
""" Mapping class that references keys weakly. """ Mapping class that references keys weakly.
@ -142,8 +143,10 @@ class WeakKeyDictionary(UserDict.UserDict):
def __init__(self, dict=None): def __init__(self, dict=None):
self.data = {} self.data = {}
if dict is not None: self.update(dict) if dict is not None: self.update(dict)
def remove(k, data=self.data): def remove(k, selfref=ref(self)):
del data[k] self = selfref()
if self is not None:
del self.data[k]
self._remove = remove self._remove = remove
def __delitem__(self, key): def __delitem__(self, key):