]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
authorRaymond Hettinger <python@rcn.com>
Thu, 19 Aug 2004 21:32:06 +0000 (21:32 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 19 Aug 2004 21:32:06 +0000 (21:32 +0000)
* Check the found object for a None value during a contains/has_key
  lookup.  Perhaps it will help the OP who is likely suffering from an
  occassional GC or threading object deletion after self.data is checked.

* Complete the previous patch by removing the unnecessary indirection
  for weak dict iterators.  Makes the code cleaner and more readable.

Lib/weakref.py

index 9373f024057b7c7706a29e43dcf16a29f8b03270..77a41b109c96822c2f0917e85e04e53e59847b67 100644 (file)
@@ -57,6 +57,20 @@ class WeakValueDictionary(UserDict.UserDict):
         else:
             return o
 
+    def __contains__(self, key):
+        try:
+            o = self.data[key]()
+        except KeyError:
+            return False
+        return o is not None
+
+    def has_key(self, key):
+        try:
+            o = self.data[key]()
+        except KeyError:
+            return False
+        return o is not None
+
     def __repr__(self):
         return "<WeakValueDictionary at %s>" % id(self)
 
@@ -93,14 +107,22 @@ class WeakValueDictionary(UserDict.UserDict):
         return L
 
     def iteritems(self):
-        return WeakValuedItemIterator(self)
+        for wr in self.data.itervalues():
+            value = wr()
+            if value is not None:
+                yield wr.key, value
 
     def iterkeys(self):
         return self.data.iterkeys()
-    __iter__ = iterkeys
+
+    def __iter__(self):
+        return self.data.iterkeys()
 
     def itervalues(self):
-        return WeakValuedValueIterator(self)
+        for wr in self.data.itervalues():
+            obj = wr()
+            if obj is not None:
+                yield obj
 
     def popitem(self):
         while 1:
@@ -236,11 +258,19 @@ class WeakKeyDictionary(UserDict.UserDict):
         return L
 
     def iteritems(self):
-        return WeakKeyedItemIterator(self)
+        for wr, value in self.data.iteritems():
+            key = wr()
+            if key is not None:
+                yield key, value
 
     def iterkeys(self):
-        return WeakKeyedKeyIterator(self)
-    __iter__ = iterkeys
+        for wr in self.data.iterkeys():
+            obj = wr()
+            if obj is not None:
+                yield obj
+
+    def __iter__(self):
+        return self.iterkeys()
 
     def itervalues(self):
         return self.data.itervalues()
@@ -275,28 +305,3 @@ class WeakKeyDictionary(UserDict.UserDict):
                 d[ref(key, self._remove)] = value
         if len(kwargs):
             self.update(kwargs)
-
-
-def WeakKeyedKeyIterator(weakdict):
-    for wr in weakdict.data.iterkeys():
-        obj = wr()
-        if obj is not None:
-            yield obj
-
-def WeakKeyedItemIterator(weakdict):
-    for wr, value in weakdict.data.iteritems():
-        key = wr()
-        if key is not None:
-            yield key, value
-
-def WeakValuedValueIterator(weakdict):
-    for wr in weakdict.data.itervalues():
-        obj = wr()
-        if obj is not None:
-            yield obj
-
-def WeakValuedItemIterator(weakdict):
-    for wr in weakdict.data.itervalues():
-        value = wr()
-        if value is not None:
-            yield wr.key, value