mirror of https://github.com/python/cpython
SF #1479988: add methods to allow access to weakrefs for the
weakref.WeakKeyDictionary and weakref.WeakValueDictionary
This commit is contained in:
parent
a6d01cec3f
commit
017e68c413
|
@ -147,6 +147,24 @@ information.
|
||||||
to vanish "by magic" (as a side effect of garbage collection).}
|
to vanish "by magic" (as a side effect of garbage collection).}
|
||||||
\end{classdesc}
|
\end{classdesc}
|
||||||
|
|
||||||
|
\class{WeakKeyDictionary} objects have the following additional
|
||||||
|
methods. These expose the internal references directly. The
|
||||||
|
references are not guaranteed to be ``live'' at the time they are
|
||||||
|
used, so the result of calling the references needs to be checked
|
||||||
|
before being used. This can be used to avoid creating references that
|
||||||
|
will cause the garbage collector to keep the keys around longer than
|
||||||
|
needed.
|
||||||
|
|
||||||
|
\begin{methoddesc}{iterkeyrefs}{}
|
||||||
|
Return an iterator that yields the weak references to the keys.
|
||||||
|
\versionadded{2.5}
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{keyrefs}{}
|
||||||
|
Return a list of weak references to the keys.
|
||||||
|
\versionadded{2.5}
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
\begin{classdesc}{WeakValueDictionary}{\optional{dict}}
|
\begin{classdesc}{WeakValueDictionary}{\optional{dict}}
|
||||||
Mapping class that references values weakly. Entries in the
|
Mapping class that references values weakly. Entries in the
|
||||||
dictionary will be discarded when no strong reference to the value
|
dictionary will be discarded when no strong reference to the value
|
||||||
|
@ -160,6 +178,21 @@ information.
|
||||||
to vanish "by magic" (as a side effect of garbage collection).}
|
to vanish "by magic" (as a side effect of garbage collection).}
|
||||||
\end{classdesc}
|
\end{classdesc}
|
||||||
|
|
||||||
|
\class{WeakValueDictionary} objects have the following additional
|
||||||
|
methods. These method have the same issues as the
|
||||||
|
\method{iterkeyrefs()} and \method{keyrefs()} methods of
|
||||||
|
\class{WeakKeyDictionary} objects.
|
||||||
|
|
||||||
|
\begin{methoddesc}{itervaluerefs}{}
|
||||||
|
Return an iterator that yields the weak references to the values.
|
||||||
|
\versionadded{2.5}
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
|
\begin{methoddesc}{valuerefs}{}
|
||||||
|
Return a list of weak references to the values.
|
||||||
|
\versionadded{2.5}
|
||||||
|
\end{methoddesc}
|
||||||
|
|
||||||
\begin{datadesc}{ReferenceType}
|
\begin{datadesc}{ReferenceType}
|
||||||
The type object for weak references objects.
|
The type object for weak references objects.
|
||||||
\end{datadesc}
|
\end{datadesc}
|
||||||
|
|
|
@ -769,10 +769,54 @@ class MappingTestCase(TestBase):
|
||||||
dict, objects = self.make_weak_keyed_dict()
|
dict, objects = self.make_weak_keyed_dict()
|
||||||
self.check_iters(dict)
|
self.check_iters(dict)
|
||||||
|
|
||||||
|
# Test keyrefs()
|
||||||
|
refs = dict.keyrefs()
|
||||||
|
self.assertEqual(len(refs), len(objects))
|
||||||
|
objects2 = list(objects)
|
||||||
|
for wr in refs:
|
||||||
|
ob = wr()
|
||||||
|
self.assert_(dict.has_key(ob))
|
||||||
|
self.assert_(ob in dict)
|
||||||
|
self.assertEqual(ob.arg, dict[ob])
|
||||||
|
objects2.remove(ob)
|
||||||
|
self.assertEqual(len(objects2), 0)
|
||||||
|
|
||||||
|
# Test iterkeyrefs()
|
||||||
|
objects2 = list(objects)
|
||||||
|
self.assertEqual(len(list(dict.iterkeyrefs())), len(objects))
|
||||||
|
for wr in dict.iterkeyrefs():
|
||||||
|
ob = wr()
|
||||||
|
self.assert_(dict.has_key(ob))
|
||||||
|
self.assert_(ob in dict)
|
||||||
|
self.assertEqual(ob.arg, dict[ob])
|
||||||
|
objects2.remove(ob)
|
||||||
|
self.assertEqual(len(objects2), 0)
|
||||||
|
|
||||||
def test_weak_valued_iters(self):
|
def test_weak_valued_iters(self):
|
||||||
dict, objects = self.make_weak_valued_dict()
|
dict, objects = self.make_weak_valued_dict()
|
||||||
self.check_iters(dict)
|
self.check_iters(dict)
|
||||||
|
|
||||||
|
# Test valuerefs()
|
||||||
|
refs = dict.valuerefs()
|
||||||
|
self.assertEqual(len(refs), len(objects))
|
||||||
|
objects2 = list(objects)
|
||||||
|
for wr in refs:
|
||||||
|
ob = wr()
|
||||||
|
self.assertEqual(ob, dict[ob.arg])
|
||||||
|
self.assertEqual(ob.arg, dict[ob.arg].arg)
|
||||||
|
objects2.remove(ob)
|
||||||
|
self.assertEqual(len(objects2), 0)
|
||||||
|
|
||||||
|
# Test itervaluerefs()
|
||||||
|
objects2 = list(objects)
|
||||||
|
self.assertEqual(len(list(dict.itervaluerefs())), len(objects))
|
||||||
|
for wr in dict.itervaluerefs():
|
||||||
|
ob = wr()
|
||||||
|
self.assertEqual(ob, dict[ob.arg])
|
||||||
|
self.assertEqual(ob.arg, dict[ob.arg].arg)
|
||||||
|
objects2.remove(ob)
|
||||||
|
self.assertEqual(len(objects2), 0)
|
||||||
|
|
||||||
def check_iters(self, dict):
|
def check_iters(self, dict):
|
||||||
# item iterator:
|
# item iterator:
|
||||||
items = dict.items()
|
items = dict.items()
|
||||||
|
|
|
@ -118,6 +118,18 @@ class WeakValueDictionary(UserDict.UserDict):
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self.data.iterkeys()
|
return self.data.iterkeys()
|
||||||
|
|
||||||
|
def itervaluerefs(self):
|
||||||
|
"""Return an iterator that yields the weak references to the values.
|
||||||
|
|
||||||
|
The references are not guaranteed to be 'live' at the time
|
||||||
|
they are used, so the result of calling the references needs
|
||||||
|
to be checked before being used. This can be used to avoid
|
||||||
|
creating references that will cause the garbage collector to
|
||||||
|
keep the values around longer than needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.data.itervalues()
|
||||||
|
|
||||||
def itervalues(self):
|
def itervalues(self):
|
||||||
for wr in self.data.itervalues():
|
for wr in self.data.itervalues():
|
||||||
obj = wr()
|
obj = wr()
|
||||||
|
@ -162,6 +174,18 @@ class WeakValueDictionary(UserDict.UserDict):
|
||||||
if len(kwargs):
|
if len(kwargs):
|
||||||
self.update(kwargs)
|
self.update(kwargs)
|
||||||
|
|
||||||
|
def valuerefs(self):
|
||||||
|
"""Return a list of weak references to the values.
|
||||||
|
|
||||||
|
The references are not guaranteed to be 'live' at the time
|
||||||
|
they are used, so the result of calling the references needs
|
||||||
|
to be checked before being used. This can be used to avoid
|
||||||
|
creating references that will cause the garbage collector to
|
||||||
|
keep the values around longer than needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.data.values()
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
L = []
|
L = []
|
||||||
for wr in self.data.values():
|
for wr in self.data.values():
|
||||||
|
@ -263,6 +287,18 @@ class WeakKeyDictionary(UserDict.UserDict):
|
||||||
if key is not None:
|
if key is not None:
|
||||||
yield key, value
|
yield key, value
|
||||||
|
|
||||||
|
def iterkeyrefs(self):
|
||||||
|
"""Return an iterator that yields the weak references to the keys.
|
||||||
|
|
||||||
|
The references are not guaranteed to be 'live' at the time
|
||||||
|
they are used, so the result of calling the references needs
|
||||||
|
to be checked before being used. This can be used to avoid
|
||||||
|
creating references that will cause the garbage collector to
|
||||||
|
keep the keys around longer than needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.data.iterkeys()
|
||||||
|
|
||||||
def iterkeys(self):
|
def iterkeys(self):
|
||||||
for wr in self.data.iterkeys():
|
for wr in self.data.iterkeys():
|
||||||
obj = wr()
|
obj = wr()
|
||||||
|
@ -275,6 +311,18 @@ class WeakKeyDictionary(UserDict.UserDict):
|
||||||
def itervalues(self):
|
def itervalues(self):
|
||||||
return self.data.itervalues()
|
return self.data.itervalues()
|
||||||
|
|
||||||
|
def keyrefs(self):
|
||||||
|
"""Return a list of weak references to the keys.
|
||||||
|
|
||||||
|
The references are not guaranteed to be 'live' at the time
|
||||||
|
they are used, so the result of calling the references needs
|
||||||
|
to be checked before being used. This can be used to avoid
|
||||||
|
creating references that will cause the garbage collector to
|
||||||
|
keep the keys around longer than needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.data.keys()
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
L = []
|
L = []
|
||||||
for wr in self.data.keys():
|
for wr in self.data.keys():
|
||||||
|
|
Loading…
Reference in New Issue