mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	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
					
				
					 3 changed files with 125 additions and 0 deletions
				
			
		|  | @ -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 @@ def test_weak_keyed_iters(self): | ||||||
|         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 @@ def iterkeys(self): | ||||||
|     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 @@ def update(self, dict=None, **kwargs): | ||||||
|         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 @@ def iteritems(self): | ||||||
|             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 @@ def __iter__(self): | ||||||
|     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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fred Drake
						Fred Drake