diff options
author | Fred Drake <fdrake@acm.org> | 2006-05-02 06:53:59 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2006-05-02 06:53:59 (GMT) |
commit | 017e68c413be6262eb1e71b0f0c5676d6db33a43 (patch) | |
tree | d9d2649217fc7fc9a2eb2f98870f434a1f1d37ae | |
parent | a6d01cec3ff3b945565653f96141c693af639924 (diff) | |
download | cpython-017e68c413be6262eb1e71b0f0c5676d6db33a43.zip cpython-017e68c413be6262eb1e71b0f0c5676d6db33a43.tar.gz cpython-017e68c413be6262eb1e71b0f0c5676d6db33a43.tar.bz2 |
SF #1479988: add methods to allow access to weakrefs for the
weakref.WeakKeyDictionary and weakref.WeakValueDictionary
-rw-r--r-- | Doc/lib/libweakref.tex | 33 | ||||
-rw-r--r-- | Lib/test/test_weakref.py | 44 | ||||
-rw-r--r-- | Lib/weakref.py | 48 |
3 files changed, 125 insertions, 0 deletions
diff --git a/Doc/lib/libweakref.tex b/Doc/lib/libweakref.tex index 840b674..fc949e6 100644 --- a/Doc/lib/libweakref.tex +++ b/Doc/lib/libweakref.tex @@ -147,6 +147,24 @@ information. to vanish "by magic" (as a side effect of garbage collection).} \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}} Mapping class that references values weakly. Entries in the 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).} \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} The type object for weak references objects. \end{datadesc} diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 9634ef2..392e5fa 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -769,10 +769,54 @@ class MappingTestCase(TestBase): dict, objects = self.make_weak_keyed_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): dict, objects = self.make_weak_valued_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): # item iterator: items = dict.items() diff --git a/Lib/weakref.py b/Lib/weakref.py index 09bd0be..4f6d757 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -118,6 +118,18 @@ class WeakValueDictionary(UserDict.UserDict): def __iter__(self): 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): for wr in self.data.itervalues(): obj = wr() @@ -162,6 +174,18 @@ class WeakValueDictionary(UserDict.UserDict): if len(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): L = [] for wr in self.data.values(): @@ -263,6 +287,18 @@ class WeakKeyDictionary(UserDict.UserDict): if key is not None: 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): for wr in self.data.iterkeys(): obj = wr() @@ -275,6 +311,18 @@ class WeakKeyDictionary(UserDict.UserDict): def itervalues(self): 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): L = [] for wr in self.data.keys(): |