From 61146790992e0a00b76a6bf6ecc9e53289a1ecd7 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 19 Aug 2004 21:32:06 +0000 Subject: 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. --- Lib/weakref.py | 67 +++++++++++++++++++++++++++++++--------------------------- 1 file 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 "" % 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 -- cgit v0.12