[Python-checkins] python/dist/src/Lib weakref.py,1.22,1.23

fdrake at users.sourceforge.net fdrake at users.sourceforge.net
Fri Jul 2 14:58:19 EDT 2004


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8493/Lib

Modified Files:
	weakref.py 
Log Message:
Make weak references subclassable:

- weakref.ref and weakref.ReferenceType will become aliases for each
  other

- weakref.ref will be a modern, new-style class with proper __new__
  and __init__ methods

- weakref.WeakValueDictionary will have a lighter memory footprint,
  using a new weakref.ref subclass to associate the key with the
  value, allowing us to have only a single object of overhead for each
  dictionary entry (currently, there are 3 objects of overhead per
  entry: a weakref to the value, a weakref to the dictionary, and a
  function object used as a weakref callback; the weakref to the
  dictionary could be avoided without this change)

- a new macro, PyWeakref_CheckRefExact(), will be added

- PyWeakref_CheckRef() will check for subclasses of weakref.ref

This closes SF patch #983019.


Index: weakref.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/weakref.py,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** weakref.py	27 May 2004 18:16:25 -0000	1.22
--- weakref.py	2 Jul 2004 18:57:42 -0000	1.23
***************
*** 43,46 ****
--- 43,54 ----
      # way in).
  
+     def __init__(self, *args, **kw):
+         UserDict.UserDict.__init__(self, *args, **kw)
+         def remove(wr, selfref=ref(self)):
+             self = selfref()
+             if self is not None:
+                 del self.data[wr.key]
+         self._remove = remove
+ 
      def __getitem__(self, key):
          o = self.data[key]()
***************
*** 54,58 ****
  
      def __setitem__(self, key, value):
!         self.data[key] = ref(value, self.__makeremove(key))
  
      def copy(self):
--- 62,66 ----
  
      def __setitem__(self, key, value):
!         self.data[key] = KeyedRef(value, self._remove, key)
  
      def copy(self):
***************
*** 118,122 ****
              wr = self.data[key]
          except KeyError:
!             self.data[key] = ref(default, self.__makeremove(key))
              return default
          else:
--- 126,130 ----
              wr = self.data[key]
          except KeyError:
!             self.data[key] = KeyedRef(default, self._remove, key)
              return default
          else:
***************
*** 129,133 ****
                  dict = type({})(dict)
              for key, o in dict.items():
!                 d[key] = ref(o, self.__makeremove(key))
          if len(kwargs):
              self.update(kwargs)
--- 137,141 ----
                  dict = type({})(dict)
              for key, o in dict.items():
!                 d[key] = KeyedRef(o, self._remove, key)
          if len(kwargs):
              self.update(kwargs)
***************
*** 141,150 ****
          return L
  
!     def __makeremove(self, key):
!         def remove(o, selfref=ref(self), key=key):
!             self = selfref()
!             if self is not None:
!                 del self.data[key]
!         return remove
  
  
--- 149,172 ----
          return L
  
! 
! class KeyedRef(ref):
!     """Specialized reference that includes a key corresponding to the value.
! 
!     This is used in the WeakValueDictionary to avoid having to create
!     a function object for each key stored in the mapping.  A shared
!     callback object can use the 'key' attribute of a KeyedRef instead
!     of getting a reference to the key from an enclosing scope.
! 
!     """
! 
!     __slots__ = "key",
! 
!     def __new__(type, ob, callback, key):
!         self = ref.__new__(type, ob, callback)
!         self.key = key
!         return self
! 
!     def __init__(self, ob, callback, key):
!         super(KeyedRef,  self).__init__(ob, callback)
  
  
***************
*** 299,312 ****
  class WeakValuedItemIterator(BaseIter):
      def __init__(self, weakdict):
!         self._next = weakdict.data.iteritems().next
  
      def next(self):
          while 1:
!             key, wr = self._next()
              value = wr()
              if value is not None:
!                 return key, value
! 
! 
! # no longer needed
! del UserDict
--- 321,330 ----
  class WeakValuedItemIterator(BaseIter):
      def __init__(self, weakdict):
!         self._next = weakdict.data.itervalues().next
  
      def next(self):
          while 1:
!             wr = self._next()
              value = wr()
              if value is not None:
!                 return wr.key, value




More information about the Python-checkins mailing list