PyXR

c:\python24\lib \ weakref.py



0001 """Weak reference support for Python.
0002 
0003 This module is an implementation of PEP 205:
0004 
0005 http://python.sourceforge.net/peps/pep-0205.html
0006 """
0007 
0008 # Naming convention: Variables named "wr" are weak reference objects;
0009 # they are called this instead of "ref" to avoid name collisions with
0010 # the module-global ref() function imported from _weakref.
0011 
0012 import UserDict
0013 
0014 from _weakref import (
0015      getweakrefcount,
0016      getweakrefs,
0017      ref,
0018      proxy,
0019      CallableProxyType,
0020      ProxyType,
0021      ReferenceType)
0022 
0023 from exceptions import ReferenceError
0024 
0025 
0026 ProxyTypes = (ProxyType, CallableProxyType)
0027 
0028 __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
0029            "WeakKeyDictionary", "ReferenceType", "ProxyType",
0030            "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
0031 
0032 
0033 class WeakValueDictionary(UserDict.UserDict):
0034     """Mapping class that references values weakly.
0035 
0036     Entries in the dictionary will be discarded when no strong
0037     reference to the value exists anymore
0038     """
0039     # We inherit the constructor without worrying about the input
0040     # dictionary; since it uses our .update() method, we get the right
0041     # checks (if the other dictionary is a WeakValueDictionary,
0042     # objects are unwrapped on the way out, and we always wrap on the
0043     # way in).
0044 
0045     def __init__(self, *args, **kw):
0046         UserDict.UserDict.__init__(self, *args, **kw)
0047         def remove(wr, selfref=ref(self)):
0048             self = selfref()
0049             if self is not None:
0050                 del self.data[wr.key]
0051         self._remove = remove
0052 
0053     def __getitem__(self, key):
0054         o = self.data[key]()
0055         if o is None:
0056             raise KeyError, key
0057         else:
0058             return o
0059 
0060     def __contains__(self, key):
0061         try:
0062             o = self.data[key]()
0063         except KeyError:
0064             return False
0065         return o is not None
0066 
0067     def has_key(self, key):
0068         try:
0069             o = self.data[key]()
0070         except KeyError:
0071             return False
0072         return o is not None
0073 
0074     def __repr__(self):
0075         return "<WeakValueDictionary at %s>" % id(self)
0076 
0077     def __setitem__(self, key, value):
0078         self.data[key] = KeyedRef(value, self._remove, key)
0079 
0080     def copy(self):
0081         new = WeakValueDictionary()
0082         for key, wr in self.data.items():
0083             o = wr()
0084             if o is not None:
0085                 new[key] = o
0086         return new
0087 
0088     def get(self, key, default=None):
0089         try:
0090             wr = self.data[key]
0091         except KeyError:
0092             return default
0093         else:
0094             o = wr()
0095             if o is None:
0096                 # This should only happen
0097                 return default
0098             else:
0099                 return o
0100 
0101     def items(self):
0102         L = []
0103         for key, wr in self.data.items():
0104             o = wr()
0105             if o is not None:
0106                 L.append((key, o))
0107         return L
0108 
0109     def iteritems(self):
0110         for wr in self.data.itervalues():
0111             value = wr()
0112             if value is not None:
0113                 yield wr.key, value
0114 
0115     def iterkeys(self):
0116         return self.data.iterkeys()
0117 
0118     def __iter__(self):
0119         return self.data.iterkeys()
0120 
0121     def itervalues(self):
0122         for wr in self.data.itervalues():
0123             obj = wr()
0124             if obj is not None:
0125                 yield obj
0126 
0127     def popitem(self):
0128         while 1:
0129             key, wr = self.data.popitem()
0130             o = wr()
0131             if o is not None:
0132                 return key, o
0133 
0134     def pop(self, key, *args):
0135         try:
0136             o = self.data.pop(key)()
0137         except KeyError:
0138             if args:
0139                 return args[0]
0140             raise
0141         if o is None:
0142             raise KeyError, key
0143         else:
0144             return o
0145 
0146     def setdefault(self, key, default=None):
0147         try:
0148             wr = self.data[key]
0149         except KeyError:
0150             self.data[key] = KeyedRef(default, self._remove, key)
0151             return default
0152         else:
0153             return wr()
0154 
0155     def update(self, dict=None, **kwargs):
0156         d = self.data
0157         if dict is not None:
0158             if not hasattr(dict, "items"):
0159                 dict = type({})(dict)
0160             for key, o in dict.items():
0161                 d[key] = KeyedRef(o, self._remove, key)
0162         if len(kwargs):
0163             self.update(kwargs)
0164 
0165     def values(self):
0166         L = []
0167         for wr in self.data.values():
0168             o = wr()
0169             if o is not None:
0170                 L.append(o)
0171         return L
0172 
0173 
0174 class KeyedRef(ref):
0175     """Specialized reference that includes a key corresponding to the value.
0176 
0177     This is used in the WeakValueDictionary to avoid having to create
0178     a function object for each key stored in the mapping.  A shared
0179     callback object can use the 'key' attribute of a KeyedRef instead
0180     of getting a reference to the key from an enclosing scope.
0181 
0182     """
0183 
0184     __slots__ = "key",
0185 
0186     def __new__(type, ob, callback, key):
0187         self = ref.__new__(type, ob, callback)
0188         self.key = key
0189         return self
0190 
0191     def __init__(self, ob, callback, key):
0192         super(KeyedRef,  self).__init__(ob, callback)
0193 
0194 
0195 class WeakKeyDictionary(UserDict.UserDict):
0196     """ Mapping class that references keys weakly.
0197 
0198     Entries in the dictionary will be discarded when there is no
0199     longer a strong reference to the key. This can be used to
0200     associate additional data with an object owned by other parts of
0201     an application without adding attributes to those objects. This
0202     can be especially useful with objects that override attribute
0203     accesses.
0204     """
0205 
0206     def __init__(self, dict=None):
0207         self.data = {}
0208         def remove(k, selfref=ref(self)):
0209             self = selfref()
0210             if self is not None:
0211                 del self.data[k]
0212         self._remove = remove
0213         if dict is not None: self.update(dict)
0214 
0215     def __delitem__(self, key):
0216         del self.data[ref(key)]
0217 
0218     def __getitem__(self, key):
0219         return self.data[ref(key)]
0220 
0221     def __repr__(self):
0222         return "<WeakKeyDictionary at %s>" % id(self)
0223 
0224     def __setitem__(self, key, value):
0225         self.data[ref(key, self._remove)] = value
0226 
0227     def copy(self):
0228         new = WeakKeyDictionary()
0229         for key, value in self.data.items():
0230             o = key()
0231             if o is not None:
0232                 new[o] = value
0233         return new
0234 
0235     def get(self, key, default=None):
0236         return self.data.get(ref(key),default)
0237 
0238     def has_key(self, key):
0239         try:
0240             wr = ref(key)
0241         except TypeError:
0242             return 0
0243         return wr in self.data
0244 
0245     def __contains__(self, key):
0246         try:
0247             wr = ref(key)
0248         except TypeError:
0249             return 0
0250         return wr in self.data
0251 
0252     def items(self):
0253         L = []
0254         for key, value in self.data.items():
0255             o = key()
0256             if o is not None:
0257                 L.append((o, value))
0258         return L
0259 
0260     def iteritems(self):
0261         for wr, value in self.data.iteritems():
0262             key = wr()
0263             if key is not None:
0264                 yield key, value
0265 
0266     def iterkeys(self):
0267         for wr in self.data.iterkeys():
0268             obj = wr()
0269             if obj is not None:
0270                 yield obj
0271 
0272     def __iter__(self):
0273         return self.iterkeys()
0274 
0275     def itervalues(self):
0276         return self.data.itervalues()
0277 
0278     def keys(self):
0279         L = []
0280         for wr in self.data.keys():
0281             o = wr()
0282             if o is not None:
0283                 L.append(o)
0284         return L
0285 
0286     def popitem(self):
0287         while 1:
0288             key, value = self.data.popitem()
0289             o = key()
0290             if o is not None:
0291                 return o, value
0292 
0293     def pop(self, key, *args):
0294         return self.data.pop(ref(key), *args)
0295 
0296     def setdefault(self, key, default=None):
0297         return self.data.setdefault(ref(key, self._remove),default)
0298 
0299     def update(self, dict=None, **kwargs):
0300         d = self.data
0301         if dict is not None:
0302             if not hasattr(dict, "items"):
0303                 dict = type({})(dict)
0304             for key, value in dict.items():
0305                 d[ref(key, self._remove)] = value
0306         if len(kwargs):
0307             self.update(kwargs)
0308 

Generated by PyXR 0.9.4
SourceForge.net Logo