source: python/vendor/Python-2.6.5/Lib/weakref.py

Last change on this file was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 9.9 KB
Line 
1"""Weak reference support for Python.
2
3This module is an implementation of PEP 205:
4
5http://www.python.org/dev/peps/pep-0205/
6"""
7
8# Naming convention: Variables named "wr" are weak reference objects;
9# they are called this instead of "ref" to avoid name collisions with
10# the module-global ref() function imported from _weakref.
11
12import UserDict
13
14from _weakref import (
15 getweakrefcount,
16 getweakrefs,
17 ref,
18 proxy,
19 CallableProxyType,
20 ProxyType,
21 ReferenceType)
22
23from exceptions import ReferenceError
24
25
26ProxyTypes = (ProxyType, CallableProxyType)
27
28__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
29 "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType",
30 "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
31
32
33class WeakValueDictionary(UserDict.UserDict):
34 """Mapping class that references values weakly.
35
36 Entries in the dictionary will be discarded when no strong
37 reference to the value exists anymore
38 """
39 # We inherit the constructor without worrying about the input
40 # dictionary; since it uses our .update() method, we get the right
41 # checks (if the other dictionary is a WeakValueDictionary,
42 # objects are unwrapped on the way out, and we always wrap on the
43 # way in).
44
45 def __init__(self, *args, **kw):
46 def remove(wr, selfref=ref(self)):
47 self = selfref()
48 if self is not None:
49 del self.data[wr.key]
50 self._remove = remove
51 UserDict.UserDict.__init__(self, *args, **kw)
52
53 def __getitem__(self, key):
54 o = self.data[key]()
55 if o is None:
56 raise KeyError, key
57 else:
58 return o
59
60 def __contains__(self, key):
61 try:
62 o = self.data[key]()
63 except KeyError:
64 return False
65 return o is not None
66
67 def has_key(self, key):
68 try:
69 o = self.data[key]()
70 except KeyError:
71 return False
72 return o is not None
73
74 def __repr__(self):
75 return "<WeakValueDictionary at %s>" % id(self)
76
77 def __setitem__(self, key, value):
78 self.data[key] = KeyedRef(value, self._remove, key)
79
80 def copy(self):
81 new = WeakValueDictionary()
82 for key, wr in self.data.items():
83 o = wr()
84 if o is not None:
85 new[key] = o
86 return new
87
88 def get(self, key, default=None):
89 try:
90 wr = self.data[key]
91 except KeyError:
92 return default
93 else:
94 o = wr()
95 if o is None:
96 # This should only happen
97 return default
98 else:
99 return o
100
101 def items(self):
102 L = []
103 for key, wr in self.data.items():
104 o = wr()
105 if o is not None:
106 L.append((key, o))
107 return L
108
109 def iteritems(self):
110 for wr in self.data.itervalues():
111 value = wr()
112 if value is not None:
113 yield wr.key, value
114
115 def iterkeys(self):
116 return self.data.iterkeys()
117
118 def __iter__(self):
119 return self.data.iterkeys()
120
121 def itervaluerefs(self):
122 """Return an iterator that yields the weak references to the values.
123
124 The references are not guaranteed to be 'live' at the time
125 they are used, so the result of calling the references needs
126 to be checked before being used. This can be used to avoid
127 creating references that will cause the garbage collector to
128 keep the values around longer than needed.
129
130 """
131 return self.data.itervalues()
132
133 def itervalues(self):
134 for wr in self.data.itervalues():
135 obj = wr()
136 if obj is not None:
137 yield obj
138
139 def popitem(self):
140 while 1:
141 key, wr = self.data.popitem()
142 o = wr()
143 if o is not None:
144 return key, o
145
146 def pop(self, key, *args):
147 try:
148 o = self.data.pop(key)()
149 except KeyError:
150 if args:
151 return args[0]
152 raise
153 if o is None:
154 raise KeyError, key
155 else:
156 return o
157
158 def setdefault(self, key, default=None):
159 try:
160 wr = self.data[key]
161 except KeyError:
162 self.data[key] = KeyedRef(default, self._remove, key)
163 return default
164 else:
165 return wr()
166
167 def update(self, dict=None, **kwargs):
168 d = self.data
169 if dict is not None:
170 if not hasattr(dict, "items"):
171 dict = type({})(dict)
172 for key, o in dict.items():
173 d[key] = KeyedRef(o, self._remove, key)
174 if len(kwargs):
175 self.update(kwargs)
176
177 def valuerefs(self):
178 """Return a list of weak references to the values.
179
180 The references are not guaranteed to be 'live' at the time
181 they are used, so the result of calling the references needs
182 to be checked before being used. This can be used to avoid
183 creating references that will cause the garbage collector to
184 keep the values around longer than needed.
185
186 """
187 return self.data.values()
188
189 def values(self):
190 L = []
191 for wr in self.data.values():
192 o = wr()
193 if o is not None:
194 L.append(o)
195 return L
196
197
198class KeyedRef(ref):
199 """Specialized reference that includes a key corresponding to the value.
200
201 This is used in the WeakValueDictionary to avoid having to create
202 a function object for each key stored in the mapping. A shared
203 callback object can use the 'key' attribute of a KeyedRef instead
204 of getting a reference to the key from an enclosing scope.
205
206 """
207
208 __slots__ = "key",
209
210 def __new__(type, ob, callback, key):
211 self = ref.__new__(type, ob, callback)
212 self.key = key
213 return self
214
215 def __init__(self, ob, callback, key):
216 super(KeyedRef, self).__init__(ob, callback)
217
218
219class WeakKeyDictionary(UserDict.UserDict):
220 """ Mapping class that references keys weakly.
221
222 Entries in the dictionary will be discarded when there is no
223 longer a strong reference to the key. This can be used to
224 associate additional data with an object owned by other parts of
225 an application without adding attributes to those objects. This
226 can be especially useful with objects that override attribute
227 accesses.
228 """
229
230 def __init__(self, dict=None):
231 self.data = {}
232 def remove(k, selfref=ref(self)):
233 self = selfref()
234 if self is not None:
235 del self.data[k]
236 self._remove = remove
237 if dict is not None: self.update(dict)
238
239 def __delitem__(self, key):
240 del self.data[ref(key)]
241
242 def __getitem__(self, key):
243 return self.data[ref(key)]
244
245 def __repr__(self):
246 return "<WeakKeyDictionary at %s>" % id(self)
247
248 def __setitem__(self, key, value):
249 self.data[ref(key, self._remove)] = value
250
251 def copy(self):
252 new = WeakKeyDictionary()
253 for key, value in self.data.items():
254 o = key()
255 if o is not None:
256 new[o] = value
257 return new
258
259 def get(self, key, default=None):
260 return self.data.get(ref(key),default)
261
262 def has_key(self, key):
263 try:
264 wr = ref(key)
265 except TypeError:
266 return 0
267 return wr in self.data
268
269 def __contains__(self, key):
270 try:
271 wr = ref(key)
272 except TypeError:
273 return 0
274 return wr in self.data
275
276 def items(self):
277 L = []
278 for key, value in self.data.items():
279 o = key()
280 if o is not None:
281 L.append((o, value))
282 return L
283
284 def iteritems(self):
285 for wr, value in self.data.iteritems():
286 key = wr()
287 if key is not None:
288 yield key, value
289
290 def iterkeyrefs(self):
291 """Return an iterator that yields the weak references to the keys.
292
293 The references are not guaranteed to be 'live' at the time
294 they are used, so the result of calling the references needs
295 to be checked before being used. This can be used to avoid
296 creating references that will cause the garbage collector to
297 keep the keys around longer than needed.
298
299 """
300 return self.data.iterkeys()
301
302 def iterkeys(self):
303 for wr in self.data.iterkeys():
304 obj = wr()
305 if obj is not None:
306 yield obj
307
308 def __iter__(self):
309 return self.iterkeys()
310
311 def itervalues(self):
312 return self.data.itervalues()
313
314 def keyrefs(self):
315 """Return a list of weak references to the keys.
316
317 The references are not guaranteed to be 'live' at the time
318 they are used, so the result of calling the references needs
319 to be checked before being used. This can be used to avoid
320 creating references that will cause the garbage collector to
321 keep the keys around longer than needed.
322
323 """
324 return self.data.keys()
325
326 def keys(self):
327 L = []
328 for wr in self.data.keys():
329 o = wr()
330 if o is not None:
331 L.append(o)
332 return L
333
334 def popitem(self):
335 while 1:
336 key, value = self.data.popitem()
337 o = key()
338 if o is not None:
339 return o, value
340
341 def pop(self, key, *args):
342 return self.data.pop(ref(key), *args)
343
344 def setdefault(self, key, default=None):
345 return self.data.setdefault(ref(key, self._remove),default)
346
347 def update(self, dict=None, **kwargs):
348 d = self.data
349 if dict is not None:
350 if not hasattr(dict, "items"):
351 dict = type({})(dict)
352 for key, value in dict.items():
353 d[ref(key, self._remove)] = value
354 if len(kwargs):
355 self.update(kwargs)
Note: See TracBrowser for help on using the repository browser.