Skip to content

Commit 746fe0f

Browse files
committed
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.
1 parent 43b9a08 commit 746fe0f

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

Lib/weakref.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ def __repr__(self):
5151
return "<WeakValueDictionary at %s>" % id(self)
5252

5353
def __setitem__(self, key, value):
54-
def remove(o, data=self.data, key=key):
55-
del data[key]
56-
self.data[key] = ref(value, remove)
54+
self.data[key] = ref(value, self.__makeremove(key))
5755

5856
def copy(self):
5957
new = WeakValueDictionary()
@@ -105,19 +103,15 @@ def setdefault(self, key, default):
105103
try:
106104
wr = self.data[key]
107105
except KeyError:
108-
def remove(o, data=self.data, key=key):
109-
del data[key]
110-
self.data[key] = ref(default, remove)
106+
self.data[key] = ref(default, self.__makeremove(key))
111107
return default
112108
else:
113109
return wr()
114110

115111
def update(self, dict):
116112
d = self.data
117113
for key, o in dict.items():
118-
def remove(o, data=d, key=key):
119-
del data[key]
120-
d[key] = ref(o, remove)
114+
d[key] = ref(o, self.__makeremove(key))
121115

122116
def values(self):
123117
L = []
@@ -127,6 +121,13 @@ def values(self):
127121
L.append(o)
128122
return L
129123

124+
def __makeremove(self, key):
125+
def remove(o, selfref=ref(self), key=key):
126+
self = selfref()
127+
if self is not None:
128+
del self.data[key]
129+
return remove
130+
130131

131132
class WeakKeyDictionary(UserDict.UserDict):
132133
""" Mapping class that references keys weakly.
@@ -142,8 +143,10 @@ class WeakKeyDictionary(UserDict.UserDict):
142143
def __init__(self, dict=None):
143144
self.data = {}
144145
if dict is not None: self.update(dict)
145-
def remove(k, data=self.data):
146-
del data[k]
146+
def remove(k, selfref=ref(self)):
147+
self = selfref()
148+
if self is not None:
149+
del self.data[k]
147150
self._remove = remove
148151

149152
def __delitem__(self, key):

0 commit comments

Comments
 (0)