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.
diff --git a/Lib/weakref.py b/Lib/weakref.py
index c71d04b..0cf6bf9 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -51,9 +51,7 @@
         return "<WeakValueDictionary at %s>" % 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 @@
         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 @@
     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 @@
                 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 @@
     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):