"""Weak reference support for Python. This module is an implementation of PEP 205: http://python.sourceforge.net/peps/pep-0205.html """ import UserDict from _weakref import \ getweakrefcount, \ getweakrefs, \ ref, \ proxy, \ ReferenceError, \ CallableProxyType, \ ProxyType, \ ReferenceType ProxyTypes = (ProxyType, CallableProxyType) __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", "WeakKeyDictionary", "ReferenceType", "ProxyType", "CallableProxyType", "ProxyTypes", "WeakValueDictionary"] class WeakValueDictionary(UserDict.UserDict): # We inherit the constructor without worrying about the input # dictionary; since it uses our .update() method, we get the right # checks (if the other dictionary is a WeakValueDictionary, # objects are unwrapped on the way out, and we always wrap on the # way in). def __getitem__(self, key): o = self.data.get(key)() if o is None: raise KeyError, key else: return o def __repr__(self): return "" % id(self) def __setitem__(self, key, value): def remove(o, data=self.data, key=key): del data[key] self.data[key] = ref(value, remove) def copy(self): new = WeakValueDictionary() for key, ref in self.data.items(): o = ref() if o is not None: new[key] = o return new def get(self, key, default=None): try: ref = self.data[key] except KeyError: return default else: o = ref() if o is None: # This should only happen return default else: return o def items(self): L = [] for key, ref in self.data.items(): o = ref() if o is not None: L.append((key, o)) return L def popitem(self): while 1: key, ref = self.data.popitem() o = ref() if o is not None: return key, o def setdefault(self, key, default): try: wr = self.data[key] except KeyError: def remove(o, data=self.data, key=key): del data[key] self.data[key] = ref(default, remove) return default else: return wr() def update(self, dict): d = self.data L = [] for key, o in dict.items(): def remove(o, data=d, key=key): del data[key] L.append((key, ref(o, remove))) for key, r in L: d[key] = r def values(self): L = [] for ref in self.data.values(): o = ref() if o is not None: L.append(o) return L class WeakKeyDictionary(UserDict.UserDict): def __init__(self, dict=None): self.data = {} if dict is not None: self.update(dict) def remove(k, data=self.data): del data[k] self._remove = remove def __getitem__(self, key): return self.data[ref(key)] def __repr__(self): return "" % id(self) def __setitem__(self, key, value): self.data[ref(key, self._remove)] = value def copy(self): new = WeakKeyDictionary() for key, value in self.data.items(): o = key() if o is not None: new[o] = value return new def get(self, key, default=None): return self.data.get(ref(key),default) def has_key(self, key): return self.data.has_key(ref(key)) def items(self): L = [] for key, value in self.data.items(): o = key() if o is not None: L.append((o, value)) return L def keys(self): L = [] for ref in self.data.keys(): o = ref() if o is not None: L.append(o) return L def popitem(self): while 1: key, value = self.data.popitem() o = key() if o is not None: return o, value def setdefault(self, key, default): return self.data.setdefault(ref(key, self._remove),default) def update(self, dict): d = self.data L = [] for key, value in dict.items(): L.append((ref(key, self._remove), value)) for key, r in L: d[key] = r # no longer needed del UserDict