SF 742860: WeakKeyDictionary __delitem__ uses iterkeys

Someone review this, please!  Final releases are getting close, Fred
(the weakref guy) won't be around until Tuesday, and the pre-patch
code can indeed raise spurious RuntimeErrors in the presence of
threads or mutating comparison functions.

See the bug report for my confusions:  I can't see any reason for why
__delitem__ iterated over the keys.  The new one-liner implementation
is much faster, can't raise RuntimeError, and should be better-behaved
in all respects wrt threads.

New tests test_weak_keyed_bad_delitem and
test_weak_keyed_cascading_deletes fail before this patch.

Bugfix candidate for 2.2.3 too, if someone else agrees with this patch.
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 838ff5e..09bed65 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -164,11 +164,7 @@
         if dict is not None: self.update(dict)
 
     def __delitem__(self, key):
-        for ref in self.data.iterkeys():
-            o = ref()
-            if o == key:
-                del self.data[ref]
-                return
+        del self.data[ref(key)]
 
     def __getitem__(self, key):
         return self.data[ref(key)]