summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-08-19 21:32:06 (GMT)
committerRaymond Hettinger <python@rcn.com>2004-08-19 21:32:06 (GMT)
commit61146790992e0a00b76a6bf6ecc9e53289a1ecd7 (patch)
tree20852192a2cc52157dd0ea92f3507b958fa6a9cd
parent3a3817f506801e4a1e62d8cd52e1c8aa0feb2993 (diff)
downloadcpython-61146790992e0a00b76a6bf6ecc9e53289a1ecd7.zip
cpython-61146790992e0a00b76a6bf6ecc9e53289a1ecd7.tar.gz
cpython-61146790992e0a00b76a6bf6ecc9e53289a1ecd7.tar.bz2
SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
* 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.
-rw-r--r--Lib/weakref.py67
1 files changed, 36 insertions, 31 deletions
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 9373f02..77a41b1 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -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