mirror of https://github.com/python/cpython
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:
parent
43b9a086bf
commit
746fe0fae5
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue