Kaydet (Commit) ecaab837 authored tarafından Barry Warsaw's avatar Barry Warsaw

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).
üst 6ecc5c19
...@@ -152,14 +152,9 @@ references that will cause the garbage collector to keep the keys around longer ...@@ -152,14 +152,9 @@ references that will cause the garbage collector to keep the keys around longer
than needed. than needed.
.. method:: WeakKeyDictionary.iterkeyrefs()
Return an :term:`iterator` that yields the weak references to the keys.
.. method:: WeakKeyDictionary.keyrefs() .. method:: WeakKeyDictionary.keyrefs()
Return a list of weak references to the keys. Return an :term:`iterator` that yields the weak references to the keys.
.. class:: WeakValueDictionary([dict]) .. class:: WeakValueDictionary([dict])
...@@ -176,18 +171,13 @@ than needed. ...@@ -176,18 +171,13 @@ than needed.
magic" (as a side effect of garbage collection). magic" (as a side effect of garbage collection).
:class:`WeakValueDictionary` objects have the following additional methods. :class:`WeakValueDictionary` objects have the following additional methods.
These method have the same issues as the :meth:`iterkeyrefs` and :meth:`keyrefs` These method have the same issues as the and :meth:`keyrefs` method of
methods of :class:`WeakKeyDictionary` objects. :class:`WeakKeyDictionary` objects.
.. method:: WeakValueDictionary.itervaluerefs()
Return an :term:`iterator` that yields the weak references to the values.
.. method:: WeakValueDictionary.valuerefs() .. method:: WeakValueDictionary.valuerefs()
Return a list of weak references to the values. Return an :term:`iterator` that yields the weak references to the values.
.. class:: WeakSet([elements]) .. class:: WeakSet([elements])
...@@ -290,7 +280,7 @@ the referent is accessed:: ...@@ -290,7 +280,7 @@ the referent is accessed::
def __init__(self, ob, callback=None, **annotations): def __init__(self, ob, callback=None, **annotations):
super(ExtendedRef, self).__init__(ob, callback) super(ExtendedRef, self).__init__(ob, callback)
self.__counter = 0 self.__counter = 0
for k, v in annotations.iteritems(): for k, v in annotations.items():
setattr(self, k, v) setattr(self, k, v)
def __call__(self): def __call__(self):
......
...@@ -790,8 +790,8 @@ class MappingTestCase(TestBase): ...@@ -790,8 +790,8 @@ class MappingTestCase(TestBase):
self.assertEqual(weakref.getweakrefcount(o), 1) self.assertEqual(weakref.getweakrefcount(o), 1)
self.assert_(o is dict[o.arg], self.assert_(o is dict[o.arg],
"wrong object returned by weak dict!") "wrong object returned by weak dict!")
items1 = dict.items() items1 = list(dict.items())
items2 = dict.copy().items() items2 = list(dict.copy().items())
items1.sort() items1.sort()
items2.sort() items2.sort()
self.assertEqual(items1, items2, self.assertEqual(items1, items2,
...@@ -856,8 +856,8 @@ class MappingTestCase(TestBase): ...@@ -856,8 +856,8 @@ class MappingTestCase(TestBase):
# Test iterkeyrefs() # Test iterkeyrefs()
objects2 = list(objects) objects2 = list(objects)
self.assertEqual(len(list(dict.iterkeyrefs())), len(objects)) self.assertEqual(len(list(dict.keyrefs())), len(objects))
for wr in dict.iterkeyrefs(): for wr in dict.keyrefs():
ob = wr() ob = wr()
self.assert_(ob in dict) self.assert_(ob in dict)
self.assert_(ob in dict) self.assert_(ob in dict)
...@@ -892,28 +892,28 @@ class MappingTestCase(TestBase): ...@@ -892,28 +892,28 @@ class MappingTestCase(TestBase):
def check_iters(self, dict): def check_iters(self, dict):
# item iterator: # item iterator:
items = dict.items() items = list(dict.items())
for item in dict.items(): for item in dict.items():
items.remove(item) 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__(): # key iterator, via __iter__():
keys = list(dict.keys()) keys = list(dict.keys())
for k in dict: for k in dict:
keys.remove(k) 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(): # key iterator, via iterkeys():
keys = list(dict.keys()) keys = list(dict.keys())
for k in dict.keys(): for k in dict.keys():
keys.remove(k) 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: # value iterator:
values = list(dict.values()) values = list(dict.values())
for v in dict.values(): for v in dict.values():
values.remove(v) values.remove(v)
self.assert_(len(values) == 0, self.assertFalse(values,
"itervalues() did not touch all values") "itervalues() did not touch all values")
def test_make_weak_keyed_dict_from_dict(self): def test_make_weak_keyed_dict_from_dict(self):
...@@ -1030,7 +1030,7 @@ class MappingTestCase(TestBase): ...@@ -1030,7 +1030,7 @@ class MappingTestCase(TestBase):
self.assertEqual(len(d), 2) self.assertEqual(len(d), 2)
del d[o1] del d[o1]
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertEqual(d.keys(), [o2]) self.assertEqual(list(d.keys()), [o2])
def test_weak_valued_delitem(self): def test_weak_valued_delitem(self):
d = weakref.WeakValueDictionary() d = weakref.WeakValueDictionary()
...@@ -1041,7 +1041,7 @@ class MappingTestCase(TestBase): ...@@ -1041,7 +1041,7 @@ class MappingTestCase(TestBase):
self.assertEqual(len(d), 2) self.assertEqual(len(d), 2)
del d['something'] del d['something']
self.assertEqual(len(d), 1) 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): def test_weak_keyed_bad_delitem(self):
d = weakref.WeakKeyDictionary() d = weakref.WeakKeyDictionary()
...@@ -1082,7 +1082,7 @@ class MappingTestCase(TestBase): ...@@ -1082,7 +1082,7 @@ class MappingTestCase(TestBase):
d[o] = o.value d[o] = o.value
del o # now the only strong references to keys are in objs del o # now the only strong references to keys are in objs
# Find the order in which iterkeys sees the keys. # 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__ # Reverse it, so that the iteration implementation of __delitem__
# has to keep looping to find the first object we delete. # has to keep looping to find the first object we delete.
objs.reverse() objs.reverse()
......
...@@ -106,13 +106,13 @@ class WeakValueDictionary(collections.MutableMapping): ...@@ -106,13 +106,13 @@ class WeakValueDictionary(collections.MutableMapping):
L.append((key, o)) L.append((key, o))
return L return L
def iteritems(self): def items(self):
for wr in self.data.values(): for wr in self.data.values():
value = wr() value = wr()
if value is not None: if value is not None:
yield wr.key, value yield wr.key, value
def iterkeys(self): def keys(self):
return iter(self.data.keys()) return iter(self.data.keys())
def __iter__(self): def __iter__(self):
...@@ -130,7 +130,7 @@ class WeakValueDictionary(collections.MutableMapping): ...@@ -130,7 +130,7 @@ class WeakValueDictionary(collections.MutableMapping):
""" """
return self.data.values() return self.data.values()
def itervalues(self): def values(self):
for wr in self.data.values(): for wr in self.data.values():
obj = wr() obj = wr()
if obj is not None: if obj is not None:
...@@ -186,14 +186,6 @@ class WeakValueDictionary(collections.MutableMapping): ...@@ -186,14 +186,6 @@ class WeakValueDictionary(collections.MutableMapping):
""" """
return self.data.values() 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): class KeyedRef(ref):
"""Specialized reference that includes a key corresponding to the value. """Specialized reference that includes a key corresponding to the value.
...@@ -270,20 +262,12 @@ class WeakKeyDictionary(collections.MutableMapping): ...@@ -270,20 +262,12 @@ class WeakKeyDictionary(collections.MutableMapping):
return wr in self.data return wr in self.data
def items(self): 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(): for wr, value in self.data.items():
key = wr() key = wr()
if key is not None: if key is not None:
yield key, value yield key, value
def iterkeyrefs(self): def keyrefs(self):
"""Return an iterator that yields the weak references to the keys. """Return an iterator that yields the weak references to the keys.
The references are not guaranteed to be 'live' at the time The references are not guaranteed to be 'live' at the time
...@@ -295,7 +279,7 @@ class WeakKeyDictionary(collections.MutableMapping): ...@@ -295,7 +279,7 @@ class WeakKeyDictionary(collections.MutableMapping):
""" """
return self.data.keys() return self.data.keys()
def iterkeys(self): def keys(self):
for wr in self.data.keys(): for wr in self.data.keys():
obj = wr() obj = wr()
if obj is not None: if obj is not None:
...@@ -304,7 +288,7 @@ class WeakKeyDictionary(collections.MutableMapping): ...@@ -304,7 +288,7 @@ class WeakKeyDictionary(collections.MutableMapping):
def __iter__(self): def __iter__(self):
return iter(self.keys()) return iter(self.keys())
def itervalues(self): def values(self):
return iter(self.data.values()) return iter(self.data.values())
def keyrefs(self): def keyrefs(self):
...@@ -319,14 +303,6 @@ class WeakKeyDictionary(collections.MutableMapping): ...@@ -319,14 +303,6 @@ class WeakKeyDictionary(collections.MutableMapping):
""" """
return self.data.keys() 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): def popitem(self):
while 1: while 1:
key, value = self.data.popitem() key, value = self.data.popitem()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment