Committing the patch in issue 2965, so that weakref dicts have a closer
interface to normal dictionaries.  keys(), values() and items() still return
iterators instead of views, but that can be fixed later (or not).
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 1788ac5..108cd7f 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -790,8 +790,8 @@
             self.assertEqual(weakref.getweakrefcount(o), 1)
             self.assert_(o is dict[o.arg],
                          "wrong object returned by weak dict!")
-        items1 = dict.items()
-        items2 = dict.copy().items()
+        items1 = list(dict.items())
+        items2 = list(dict.copy().items())
         items1.sort()
         items2.sort()
         self.assertEqual(items1, items2,
@@ -856,8 +856,8 @@
 
         # Test iterkeyrefs()
         objects2 = list(objects)
-        self.assertEqual(len(list(dict.iterkeyrefs())), len(objects))
-        for wr in dict.iterkeyrefs():
+        self.assertEqual(len(list(dict.keyrefs())), len(objects))
+        for wr in dict.keyrefs():
             ob = wr()
             self.assert_(ob in dict)
             self.assert_(ob in dict)
@@ -892,28 +892,28 @@
 
     def check_iters(self, dict):
         # item iterator:
-        items = dict.items()
+        items = list(dict.items())
         for item in dict.items():
             items.remove(item)
-        self.assert_(len(items) == 0, "items() did not touch all items")
+        self.assertFalse(items, "items() did not touch all items")
 
         # key iterator, via __iter__():
         keys = list(dict.keys())
         for k in dict:
             keys.remove(k)
-        self.assert_(len(keys) == 0, "__iter__() did not touch all keys")
+        self.assertFalse(keys, "__iter__() did not touch all keys")
 
         # key iterator, via iterkeys():
         keys = list(dict.keys())
         for k in dict.keys():
             keys.remove(k)
-        self.assert_(len(keys) == 0, "iterkeys() did not touch all keys")
+        self.assertFalse(keys, "iterkeys() did not touch all keys")
 
         # value iterator:
         values = list(dict.values())
         for v in dict.values():
             values.remove(v)
-        self.assert_(len(values) == 0,
+        self.assertFalse(values,
                      "itervalues() did not touch all values")
 
     def test_make_weak_keyed_dict_from_dict(self):
@@ -1030,7 +1030,7 @@
         self.assertEqual(len(d), 2)
         del d[o1]
         self.assertEqual(len(d), 1)
-        self.assertEqual(d.keys(), [o2])
+        self.assertEqual(list(d.keys()), [o2])
 
     def test_weak_valued_delitem(self):
         d = weakref.WeakValueDictionary()
@@ -1041,7 +1041,7 @@
         self.assertEqual(len(d), 2)
         del d['something']
         self.assertEqual(len(d), 1)
-        self.assert_(d.items() == [('something else', o2)])
+        self.assert_(list(d.items()) == [('something else', o2)])
 
     def test_weak_keyed_bad_delitem(self):
         d = weakref.WeakKeyDictionary()
@@ -1082,7 +1082,7 @@
             d[o] = o.value
         del o   # now the only strong references to keys are in objs
         # Find the order in which iterkeys sees the keys.
-        objs = d.keys()
+        objs = list(d.keys())
         # Reverse it, so that the iteration implementation of __delitem__
         # has to keep looping to find the first object we delete.
         objs.reverse()
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 64d962c..5f672c6 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -106,13 +106,13 @@
                 L.append((key, o))
         return L
 
-    def iteritems(self):
+    def items(self):
         for wr in self.data.values():
             value = wr()
             if value is not None:
                 yield wr.key, value
 
-    def iterkeys(self):
+    def keys(self):
         return iter(self.data.keys())
 
     def __iter__(self):
@@ -130,7 +130,7 @@
         """
         return self.data.values()
 
-    def itervalues(self):
+    def values(self):
         for wr in self.data.values():
             obj = wr()
             if obj is not None:
@@ -186,14 +186,6 @@
         """
         return self.data.values()
 
-    def values(self):
-        L = []
-        for wr in self.data.values():
-            o = wr()
-            if o is not None:
-                L.append(o)
-        return L
-
 
 class KeyedRef(ref):
     """Specialized reference that includes a key corresponding to the value.
@@ -270,20 +262,12 @@
         return wr in self.data
 
     def items(self):
-        L = []
-        for key, value in self.data.items():
-            o = key()
-            if o is not None:
-                L.append((o, value))
-        return L
-
-    def iteritems(self):
         for wr, value in self.data.items():
             key = wr()
             if key is not None:
                 yield key, value
 
-    def iterkeyrefs(self):
+    def keyrefs(self):
         """Return an iterator that yields the weak references to the keys.
 
         The references are not guaranteed to be 'live' at the time
@@ -295,7 +279,7 @@
         """
         return self.data.keys()
 
-    def iterkeys(self):
+    def keys(self):
         for wr in self.data.keys():
             obj = wr()
             if obj is not None:
@@ -304,7 +288,7 @@
     def __iter__(self):
         return iter(self.keys())
 
-    def itervalues(self):
+    def values(self):
         return iter(self.data.values())
 
     def keyrefs(self):
@@ -319,14 +303,6 @@
         """
         return self.data.keys()
 
-    def keys(self):
-        L = []
-        for wr in self.data.keys():
-            o = wr()
-            if o is not None:
-                L.append(o)
-        return L
-
     def popitem(self):
         while 1:
             key, value = self.data.popitem()