blob: 4f6d757fe3bb4a8a2efa38f5d7170713ed4649da [file] [log] [blame]
Fred Drake41deb1e2001-02-01 05:27:45 +00001"""Weak reference support for Python.
2
3This module is an implementation of PEP 205:
4
5http://python.sourceforge.net/peps/pep-0205.html
6"""
7
Fred Drakebd7f8182001-04-19 16:26:06 +00008# 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
Fred Drake41deb1e2001-02-01 05:27:45 +000012import UserDict
13
Andrew M. Kuchling33ad28b2004-08-31 11:38:12 +000014from _weakref import (
15 getweakrefcount,
16 getweakrefs,
17 ref,
18 proxy,
19 CallableProxyType,
20 ProxyType,
21 ReferenceType)
Fred Drake41deb1e2001-02-01 05:27:45 +000022
Fred Drakee0292422001-10-05 21:54:09 +000023from exceptions import ReferenceError
24
25
Fred Drake41deb1e2001-02-01 05:27:45 +000026ProxyTypes = (ProxyType, CallableProxyType)
27
Fred Drake9a9d2192001-04-10 19:11:23 +000028__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
Skip Montanaro40fc1602001-03-01 04:27:19 +000029 "WeakKeyDictionary", "ReferenceType", "ProxyType",
30 "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
Fred Drake41deb1e2001-02-01 05:27:45 +000031
Fred Drake41deb1e2001-02-01 05:27:45 +000032
Fred Drakebd7f8182001-04-19 16:26:06 +000033class 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 """
Fred Drake41deb1e2001-02-01 05:27:45 +000039 # We inherit the constructor without worrying about the input
40 # dictionary; since it uses our .update() method, we get the right
Fred Drake9d2c85d2001-03-01 03:06:03 +000041 # 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).
Fred Drake41deb1e2001-02-01 05:27:45 +000044
Fred Drake0a4dd392004-07-02 18:57:45 +000045 def __init__(self, *args, **kw):
Fred Drake0a4dd392004-07-02 18:57:45 +000046 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
Georg Brandl9166e1a2005-06-04 09:20:03 +000051 UserDict.UserDict.__init__(self, *args, **kw)
Fred Drake0a4dd392004-07-02 18:57:45 +000052
Fred Drake41deb1e2001-02-01 05:27:45 +000053 def __getitem__(self, key):
Fred Drake4fd06e02001-08-03 04:11:27 +000054 o = self.data[key]()
Fred Drake41deb1e2001-02-01 05:27:45 +000055 if o is None:
56 raise KeyError, key
57 else:
58 return o
59
Raymond Hettinger61146792004-08-19 21:32:06 +000060 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
Fred Drake41deb1e2001-02-01 05:27:45 +000074 def __repr__(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +000075 return "<WeakValueDictionary at %s>" % id(self)
Fred Drake41deb1e2001-02-01 05:27:45 +000076
77 def __setitem__(self, key, value):
Fred Drake0a4dd392004-07-02 18:57:45 +000078 self.data[key] = KeyedRef(value, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +000079
80 def copy(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +000081 new = WeakValueDictionary()
Fred Drakebd7f8182001-04-19 16:26:06 +000082 for key, wr in self.data.items():
83 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +000084 if o is not None:
85 new[key] = o
Fred Drake9d2c85d2001-03-01 03:06:03 +000086 return new
Fred Drake41deb1e2001-02-01 05:27:45 +000087
Fred Drake1d9e4b72001-04-16 17:34:48 +000088 def get(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +000089 try:
Fred Drakebd7f8182001-04-19 16:26:06 +000090 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +000091 except KeyError:
92 return default
93 else:
Fred Drakebd7f8182001-04-19 16:26:06 +000094 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +000095 if o is None:
96 # This should only happen
97 return default
98 else:
99 return o
100
101 def items(self):
Fred Drake312a5dc2001-02-02 15:13:24 +0000102 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000103 for key, wr in self.data.items():
104 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000105 if o is not None:
Fred Drake312a5dc2001-02-02 15:13:24 +0000106 L.append((key, o))
Fred Drake41deb1e2001-02-01 05:27:45 +0000107 return L
108
Fred Drake101209d2001-05-02 05:43:09 +0000109 def iteritems(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000110 for wr in self.data.itervalues():
111 value = wr()
112 if value is not None:
113 yield wr.key, value
Fred Drake101209d2001-05-02 05:43:09 +0000114
115 def iterkeys(self):
116 return self.data.iterkeys()
Raymond Hettinger61146792004-08-19 21:32:06 +0000117
118 def __iter__(self):
119 return self.data.iterkeys()
Fred Drake101209d2001-05-02 05:43:09 +0000120
Fred Drake017e68c2006-05-02 06:53:59 +0000121 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
Fred Drake101209d2001-05-02 05:43:09 +0000133 def itervalues(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000134 for wr in self.data.itervalues():
135 obj = wr()
136 if obj is not None:
137 yield obj
Fred Drake101209d2001-05-02 05:43:09 +0000138
Fred Drake41deb1e2001-02-01 05:27:45 +0000139 def popitem(self):
140 while 1:
Fred Drakebd7f8182001-04-19 16:26:06 +0000141 key, wr = self.data.popitem()
142 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000143 if o is not None:
144 return key, o
145
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000146 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
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000158 def setdefault(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +0000159 try:
Fred Drakebd7f8182001-04-19 16:26:06 +0000160 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +0000161 except KeyError:
Fred Drake0a4dd392004-07-02 18:57:45 +0000162 self.data[key] = KeyedRef(default, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +0000163 return default
164 else:
Fred Drakebd7f8182001-04-19 16:26:06 +0000165 return wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000166
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000167 def update(self, dict=None, **kwargs):
Fred Drake41deb1e2001-02-01 05:27:45 +0000168 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000169 if dict is not None:
170 if not hasattr(dict, "items"):
171 dict = type({})(dict)
172 for key, o in dict.items():
Fred Drake0a4dd392004-07-02 18:57:45 +0000173 d[key] = KeyedRef(o, self._remove, key)
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000174 if len(kwargs):
175 self.update(kwargs)
Fred Drake41deb1e2001-02-01 05:27:45 +0000176
Fred Drake017e68c2006-05-02 06:53:59 +0000177 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
Fred Drake41deb1e2001-02-01 05:27:45 +0000189 def values(self):
190 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000191 for wr in self.data.values():
192 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000193 if o is not None:
194 L.append(o)
195 return L
196
Fred Drake0a4dd392004-07-02 18:57:45 +0000197
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)
Fred Drake746fe0f2001-09-28 19:01:26 +0000217
Fred Drake41deb1e2001-02-01 05:27:45 +0000218
Martin v. Löwis5e163332001-02-27 18:36:56 +0000219class WeakKeyDictionary(UserDict.UserDict):
Fred Drakebd7f8182001-04-19 16:26:06 +0000220 """ 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 """
Martin v. Löwis5e163332001-02-27 18:36:56 +0000229
230 def __init__(self, dict=None):
231 self.data = {}
Fred Drake746fe0f2001-09-28 19:01:26 +0000232 def remove(k, selfref=ref(self)):
233 self = selfref()
234 if self is not None:
235 del self.data[k]
Martin v. Löwis5e163332001-02-27 18:36:56 +0000236 self._remove = remove
Guido van Rossum009afb72002-06-10 20:00:52 +0000237 if dict is not None: self.update(dict)
Martin v. Löwis5e163332001-02-27 18:36:56 +0000238
Fred Drakeb663a2c2001-09-06 14:51:01 +0000239 def __delitem__(self, key):
Tim Peters886128f2003-05-25 01:45:11 +0000240 del self.data[ref(key)]
Fred Drakeb663a2c2001-09-06 14:51:01 +0000241
Martin v. Löwis5e163332001-02-27 18:36:56 +0000242 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
Fred Drake9d2c85d2001-03-01 03:06:03 +0000257 return new
Martin v. Löwis5e163332001-02-27 18:36:56 +0000258
Fred Drake1d9e4b72001-04-16 17:34:48 +0000259 def get(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000260 return self.data.get(ref(key),default)
261
Fred Drake1d9e4b72001-04-16 17:34:48 +0000262 def has_key(self, key):
Fred Drake3bae7dd2001-11-06 16:36:53 +0000263 try:
264 wr = ref(key)
265 except TypeError:
266 return 0
Raymond Hettinger54f02222002-06-01 14:18:47 +0000267 return wr in self.data
Fred Drake1d9e4b72001-04-16 17:34:48 +0000268
Raymond Hettinger54f02222002-06-01 14:18:47 +0000269 def __contains__(self, key):
270 try:
271 wr = ref(key)
272 except TypeError:
273 return 0
274 return wr in self.data
Tim Petersc411dba2002-07-16 21:35:23 +0000275
Martin v. Löwis5e163332001-02-27 18:36:56 +0000276 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
Fred Drake101209d2001-05-02 05:43:09 +0000284 def iteritems(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000285 for wr, value in self.data.iteritems():
286 key = wr()
287 if key is not None:
288 yield key, value
Fred Drake101209d2001-05-02 05:43:09 +0000289
Fred Drake017e68c2006-05-02 06:53:59 +0000290 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
Fred Drake101209d2001-05-02 05:43:09 +0000302 def iterkeys(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000303 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()
Fred Drake101209d2001-05-02 05:43:09 +0000310
311 def itervalues(self):
312 return self.data.itervalues()
313
Fred Drake017e68c2006-05-02 06:53:59 +0000314 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
Fred Drake1d9e4b72001-04-16 17:34:48 +0000326 def keys(self):
327 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000328 for wr in self.data.keys():
329 o = wr()
Fred Drake1d9e4b72001-04-16 17:34:48 +0000330 if o is not None:
331 L.append(o)
332 return L
333
Martin v. Löwis5e163332001-02-27 18:36:56 +0000334 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
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000341 def pop(self, key, *args):
342 return self.data.pop(ref(key), *args)
343
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000344 def setdefault(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000345 return self.data.setdefault(ref(key, self._remove),default)
346
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000347 def update(self, dict=None, **kwargs):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000348 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000349 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)