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).
This commit is contained in:
parent
6ecc5c1980
commit
ecaab837b6
@ -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.
|
|||||||
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::
|
|||||||
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):
|
|||||||
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):
|
|||||||
|
|
||||||
# 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):
|
|||||||
|
|
||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
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):
|
|||||||
"""
|
"""
|
||||||
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):
|
|||||||
"""
|
"""
|
||||||
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):
|
|||||||
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):
|
|||||||
"""
|
"""
|
||||||
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):
|
|||||||
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):
|
|||||||
"""
|
"""
|
||||||
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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user