blob: 44cf9a7c1a1561766b4146200cecc57ac74fe848 [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
Fred Drake41deb1e2001-02-01 05:27:45 +000067 def __repr__(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +000068 return "<WeakValueDictionary at %s>" % id(self)
Fred Drake41deb1e2001-02-01 05:27:45 +000069
70 def __setitem__(self, key, value):
Fred Drake0a4dd392004-07-02 18:57:45 +000071 self.data[key] = KeyedRef(value, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +000072
73 def copy(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +000074 new = WeakValueDictionary()
Fred Drakebd7f8182001-04-19 16:26:06 +000075 for key, wr in self.data.items():
76 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +000077 if o is not None:
78 new[key] = o
Fred Drake9d2c85d2001-03-01 03:06:03 +000079 return new
Fred Drake41deb1e2001-02-01 05:27:45 +000080
Fred Drake1d9e4b72001-04-16 17:34:48 +000081 def get(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +000082 try:
Fred Drakebd7f8182001-04-19 16:26:06 +000083 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +000084 except KeyError:
85 return default
86 else:
Fred Drakebd7f8182001-04-19 16:26:06 +000087 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +000088 if o is None:
89 # This should only happen
90 return default
91 else:
92 return o
93
94 def items(self):
Fred Drake312a5dc2001-02-02 15:13:24 +000095 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +000096 for key, wr in self.data.items():
97 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +000098 if o is not None:
Fred Drake312a5dc2001-02-02 15:13:24 +000099 L.append((key, o))
Fred Drake41deb1e2001-02-01 05:27:45 +0000100 return L
101
Fred Drake101209d2001-05-02 05:43:09 +0000102 def iteritems(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000103 for wr in self.data.itervalues():
104 value = wr()
105 if value is not None:
106 yield wr.key, value
Fred Drake101209d2001-05-02 05:43:09 +0000107
108 def iterkeys(self):
109 return self.data.iterkeys()
Raymond Hettinger61146792004-08-19 21:32:06 +0000110
111 def __iter__(self):
112 return self.data.iterkeys()
Fred Drake101209d2001-05-02 05:43:09 +0000113
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 def itervaluerefs(self):
115 """Return an iterator that yields the weak references to the values.
116
117 The references are not guaranteed to be 'live' at the time
118 they are used, so the result of calling the references needs
119 to be checked before being used. This can be used to avoid
120 creating references that will cause the garbage collector to
121 keep the values around longer than needed.
122
123 """
124 return self.data.itervalues()
125
Fred Drake101209d2001-05-02 05:43:09 +0000126 def itervalues(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000127 for wr in self.data.itervalues():
128 obj = wr()
129 if obj is not None:
130 yield obj
Fred Drake101209d2001-05-02 05:43:09 +0000131
Fred Drake41deb1e2001-02-01 05:27:45 +0000132 def popitem(self):
133 while 1:
Fred Drakebd7f8182001-04-19 16:26:06 +0000134 key, wr = self.data.popitem()
135 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000136 if o is not None:
137 return key, o
138
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000139 def pop(self, key, *args):
140 try:
141 o = self.data.pop(key)()
142 except KeyError:
143 if args:
144 return args[0]
145 raise
146 if o is None:
147 raise KeyError, key
148 else:
149 return o
150
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000151 def setdefault(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +0000152 try:
Fred Drakebd7f8182001-04-19 16:26:06 +0000153 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +0000154 except KeyError:
Fred Drake0a4dd392004-07-02 18:57:45 +0000155 self.data[key] = KeyedRef(default, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +0000156 return default
157 else:
Fred Drakebd7f8182001-04-19 16:26:06 +0000158 return wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000159
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000160 def update(self, dict=None, **kwargs):
Fred Drake41deb1e2001-02-01 05:27:45 +0000161 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000162 if dict is not None:
163 if not hasattr(dict, "items"):
164 dict = type({})(dict)
165 for key, o in dict.items():
Fred Drake0a4dd392004-07-02 18:57:45 +0000166 d[key] = KeyedRef(o, self._remove, key)
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000167 if len(kwargs):
168 self.update(kwargs)
Fred Drake41deb1e2001-02-01 05:27:45 +0000169
Thomas Wouters477c8d52006-05-27 19:21:47 +0000170 def valuerefs(self):
171 """Return a list of weak references to the values.
172
173 The references are not guaranteed to be 'live' at the time
174 they are used, so the result of calling the references needs
175 to be checked before being used. This can be used to avoid
176 creating references that will cause the garbage collector to
177 keep the values around longer than needed.
178
179 """
180 return self.data.values()
181
Fred Drake41deb1e2001-02-01 05:27:45 +0000182 def values(self):
183 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000184 for wr in self.data.values():
185 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000186 if o is not None:
187 L.append(o)
188 return L
189
Fred Drake0a4dd392004-07-02 18:57:45 +0000190
191class KeyedRef(ref):
192 """Specialized reference that includes a key corresponding to the value.
193
194 This is used in the WeakValueDictionary to avoid having to create
195 a function object for each key stored in the mapping. A shared
196 callback object can use the 'key' attribute of a KeyedRef instead
197 of getting a reference to the key from an enclosing scope.
198
199 """
200
201 __slots__ = "key",
202
203 def __new__(type, ob, callback, key):
204 self = ref.__new__(type, ob, callback)
205 self.key = key
206 return self
207
208 def __init__(self, ob, callback, key):
209 super(KeyedRef, self).__init__(ob, callback)
Fred Drake746fe0f2001-09-28 19:01:26 +0000210
Fred Drake41deb1e2001-02-01 05:27:45 +0000211
Martin v. Löwis5e163332001-02-27 18:36:56 +0000212class WeakKeyDictionary(UserDict.UserDict):
Fred Drakebd7f8182001-04-19 16:26:06 +0000213 """ Mapping class that references keys weakly.
214
215 Entries in the dictionary will be discarded when there is no
216 longer a strong reference to the key. This can be used to
217 associate additional data with an object owned by other parts of
218 an application without adding attributes to those objects. This
219 can be especially useful with objects that override attribute
220 accesses.
221 """
Martin v. Löwis5e163332001-02-27 18:36:56 +0000222
223 def __init__(self, dict=None):
224 self.data = {}
Fred Drake746fe0f2001-09-28 19:01:26 +0000225 def remove(k, selfref=ref(self)):
226 self = selfref()
227 if self is not None:
228 del self.data[k]
Martin v. Löwis5e163332001-02-27 18:36:56 +0000229 self._remove = remove
Guido van Rossum009afb72002-06-10 20:00:52 +0000230 if dict is not None: self.update(dict)
Martin v. Löwis5e163332001-02-27 18:36:56 +0000231
Fred Drakeb663a2c2001-09-06 14:51:01 +0000232 def __delitem__(self, key):
Tim Peters886128f2003-05-25 01:45:11 +0000233 del self.data[ref(key)]
Fred Drakeb663a2c2001-09-06 14:51:01 +0000234
Martin v. Löwis5e163332001-02-27 18:36:56 +0000235 def __getitem__(self, key):
236 return self.data[ref(key)]
237
238 def __repr__(self):
239 return "<WeakKeyDictionary at %s>" % id(self)
240
241 def __setitem__(self, key, value):
242 self.data[ref(key, self._remove)] = value
243
244 def copy(self):
245 new = WeakKeyDictionary()
246 for key, value in self.data.items():
247 o = key()
248 if o is not None:
249 new[o] = value
Fred Drake9d2c85d2001-03-01 03:06:03 +0000250 return new
Martin v. Löwis5e163332001-02-27 18:36:56 +0000251
Fred Drake1d9e4b72001-04-16 17:34:48 +0000252 def get(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000253 return self.data.get(ref(key),default)
254
Raymond Hettinger54f02222002-06-01 14:18:47 +0000255 def __contains__(self, key):
256 try:
257 wr = ref(key)
258 except TypeError:
259 return 0
260 return wr in self.data
Tim Petersc411dba2002-07-16 21:35:23 +0000261
Martin v. Löwis5e163332001-02-27 18:36:56 +0000262 def items(self):
263 L = []
264 for key, value in self.data.items():
265 o = key()
266 if o is not None:
267 L.append((o, value))
268 return L
269
Fred Drake101209d2001-05-02 05:43:09 +0000270 def iteritems(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000271 for wr, value in self.data.iteritems():
272 key = wr()
273 if key is not None:
274 yield key, value
Fred Drake101209d2001-05-02 05:43:09 +0000275
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276 def iterkeyrefs(self):
277 """Return an iterator that yields the weak references to the keys.
278
279 The references are not guaranteed to be 'live' at the time
280 they are used, so the result of calling the references needs
281 to be checked before being used. This can be used to avoid
282 creating references that will cause the garbage collector to
283 keep the keys around longer than needed.
284
285 """
286 return self.data.iterkeys()
287
Fred Drake101209d2001-05-02 05:43:09 +0000288 def iterkeys(self):
Raymond Hettinger61146792004-08-19 21:32:06 +0000289 for wr in self.data.iterkeys():
290 obj = wr()
291 if obj is not None:
292 yield obj
293
294 def __iter__(self):
295 return self.iterkeys()
Fred Drake101209d2001-05-02 05:43:09 +0000296
297 def itervalues(self):
298 return self.data.itervalues()
299
Thomas Wouters477c8d52006-05-27 19:21:47 +0000300 def keyrefs(self):
301 """Return a list of weak references to the keys.
302
303 The references are not guaranteed to be 'live' at the time
304 they are used, so the result of calling the references needs
305 to be checked before being used. This can be used to avoid
306 creating references that will cause the garbage collector to
307 keep the keys around longer than needed.
308
309 """
310 return self.data.keys()
311
Fred Drake1d9e4b72001-04-16 17:34:48 +0000312 def keys(self):
313 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000314 for wr in self.data.keys():
315 o = wr()
Fred Drake1d9e4b72001-04-16 17:34:48 +0000316 if o is not None:
317 L.append(o)
318 return L
319
Martin v. Löwis5e163332001-02-27 18:36:56 +0000320 def popitem(self):
321 while 1:
322 key, value = self.data.popitem()
323 o = key()
324 if o is not None:
325 return o, value
326
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000327 def pop(self, key, *args):
328 return self.data.pop(ref(key), *args)
329
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000330 def setdefault(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000331 return self.data.setdefault(ref(key, self._remove),default)
332
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000333 def update(self, dict=None, **kwargs):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000334 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000335 if dict is not None:
336 if not hasattr(dict, "items"):
337 dict = type({})(dict)
338 for key, value in dict.items():
339 d[ref(key, self._remove)] = value
340 if len(kwargs):
341 self.update(kwargs)