home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_Lib_weakref.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  4.7 KB  |  184 lines

  1. """Weak reference support for Python.
  2.  
  3. This module is an implementation of PEP 205:
  4.  
  5. http://python.sourceforge.net/peps/pep-0205.html
  6. """
  7.  
  8. import UserDict
  9.  
  10. from _weakref import \
  11.      getweakrefcount, \
  12.      getweakrefs, \
  13.      ref, \
  14.      proxy, \
  15.      ReferenceError, \
  16.      CallableProxyType, \
  17.      ProxyType, \
  18.      ReferenceType
  19.  
  20. ProxyTypes = (ProxyType, CallableProxyType)
  21.  
  22. __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
  23.            "WeakKeyDictionary", "ReferenceType", "ProxyType",
  24.            "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
  25.  
  26. class WeakValueDictionary(UserDict.UserDict):
  27.  
  28.     # We inherit the constructor without worrying about the input
  29.     # dictionary; since it uses our .update() method, we get the right
  30.     # checks (if the other dictionary is a WeakValueDictionary,
  31.     # objects are unwrapped on the way out, and we always wrap on the
  32.     # way in).
  33.  
  34.     def __getitem__(self, key):
  35.         o = self.data.get(key)()
  36.         if o is None:
  37.             raise KeyError, key
  38.         else:
  39.             return o
  40.  
  41.     def __repr__(self):
  42.         return "<WeakValueDictionary at %s>" % id(self)
  43.  
  44.     def __setitem__(self, key, value):
  45.         def remove(o, data=self.data, key=key):
  46.             del data[key]
  47.         self.data[key] = ref(value, remove)
  48.  
  49.     def copy(self):
  50.         new = WeakValueDictionary()
  51.         for key, ref in self.data.items():
  52.             o = ref()
  53.             if o is not None:
  54.                 new[key] = o
  55.         return new
  56.  
  57.     def get(self, key, default=None):
  58.         try:
  59.             ref = self.data[key]
  60.         except KeyError:
  61.             return default
  62.         else:
  63.             o = ref()
  64.             if o is None:
  65.                 # This should only happen
  66.                 return default
  67.             else:
  68.                 return o
  69.  
  70.     def items(self):
  71.         L = []
  72.         for key, ref in self.data.items():
  73.             o = ref()
  74.             if o is not None:
  75.                 L.append((key, o))
  76.         return L
  77.  
  78.     def popitem(self):
  79.         while 1:
  80.             key, ref = self.data.popitem()
  81.             o = ref()
  82.             if o is not None:
  83.                 return key, o
  84.  
  85.     def setdefault(self, key, default):
  86.         try:
  87.             ref = self.data[key]
  88.         except KeyError:
  89.             def remove(o, data=self.data, key=key):
  90.                 del data[key]
  91.             ref = ref(default, remove)
  92.             self.data[key] = ref
  93.             return default
  94.         else:
  95.             return ref()
  96.  
  97.     def update(self, dict):
  98.         d = self.data
  99.         L = []
  100.         for key, o in dict.items():
  101.             def remove(o, data=d, key=key):
  102.                 del data[key]
  103.             L.append((key, ref(o, remove)))
  104.         for key, r in L:
  105.             d[key] = r
  106.  
  107.     def values(self):
  108.         L = []
  109.         for ref in self.data.values():
  110.             o = ref()
  111.             if o is not None:
  112.                 L.append(o)
  113.         return L
  114.  
  115.  
  116. class WeakKeyDictionary(UserDict.UserDict):
  117.  
  118.     def __init__(self, dict=None):
  119.         self.data = {}
  120.         if dict is not None: self.update(dict)
  121.         def remove(k, data=self.data):
  122.             del data[k]
  123.         self._remove = remove
  124.  
  125.     def __getitem__(self, key):
  126.         return self.data[ref(key)]
  127.  
  128.     def __repr__(self):
  129.         return "<WeakKeyDictionary at %s>" % id(self)
  130.  
  131.     def __setitem__(self, key, value):
  132.         self.data[ref(key, self._remove)] = value
  133.  
  134.     def copy(self):
  135.         new = WeakKeyDictionary()
  136.         for key, value in self.data.items():
  137.             o = key()
  138.             if o is not None:
  139.                 new[o] = value
  140.         return new
  141.  
  142.     def get(self, key, default=None):
  143.         return self.data.get(ref(key),default)
  144.  
  145.     def has_key(self, key):
  146.         return self.data.has_key(ref(key))
  147.  
  148.     def items(self):
  149.         L = []
  150.         for key, value in self.data.items():
  151.             o = key()
  152.             if o is not None:
  153.                 L.append((o, value))
  154.         return L
  155.  
  156.     def keys(self):
  157.         L = []
  158.         for ref in self.data.keys():
  159.             o = ref()
  160.             if o is not None:
  161.                 L.append(o)
  162.         return L
  163.  
  164.     def popitem(self):
  165.         while 1:
  166.             key, value = self.data.popitem()
  167.             o = key()
  168.             if o is not None:
  169.                 return o, value
  170.  
  171.     def setdefault(self, key, default):
  172.         return self.data.setdefault(ref(key, self._remove),default)
  173.  
  174.     def update(self, dict):
  175.         d = self.data
  176.         L = []
  177.         for key, value in dict.items():
  178.             L.append((ref(key, self._remove), value))
  179.         for key, r in L:
  180.             d[key] = r
  181.  
  182. # no longer needed
  183. del UserDict
  184.