blob: b2546f72234dbe81198649a0d71ad8a174d64f8d [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
Raymond Hettinger7ac60952008-02-05 01:15:57 +000012import collections
Fred Drake41deb1e2001-02-01 05:27:45 +000013
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
Raymond Hettinger93fa6082008-02-05 00:20:01 +000023from _weakrefset import WeakSet
Fred Drakee0292422001-10-05 21:54:09 +000024
Fred Drake41deb1e2001-02-01 05:27:45 +000025ProxyTypes = (ProxyType, CallableProxyType)
26
Fred Drake9a9d2192001-04-10 19:11:23 +000027__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
Skip Montanaro40fc1602001-03-01 04:27:19 +000028 "WeakKeyDictionary", "ReferenceType", "ProxyType",
Raymond Hettinger93fa6082008-02-05 00:20:01 +000029 "CallableProxyType", "ProxyTypes", "WeakValueDictionary",
30 "WeakSet"]
Fred Drake41deb1e2001-02-01 05:27:45 +000031
Fred Drake41deb1e2001-02-01 05:27:45 +000032
Raymond Hettinger7ac60952008-02-05 01:15:57 +000033class WeakValueDictionary(collections.MutableMapping):
Fred Drakebd7f8182001-04-19 16:26:06 +000034 """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
Raymond Hettinger7ac60952008-02-05 01:15:57 +000051 self.data = d = {}
52 d.update(*args, **kw)
Fred Drake0a4dd392004-07-02 18:57:45 +000053
Fred Drake41deb1e2001-02-01 05:27:45 +000054 def __getitem__(self, key):
Fred Drake4fd06e02001-08-03 04:11:27 +000055 o = self.data[key]()
Fred Drake41deb1e2001-02-01 05:27:45 +000056 if o is None:
Collin Winterce36ad82007-08-30 01:19:48 +000057 raise KeyError(key)
Fred Drake41deb1e2001-02-01 05:27:45 +000058 else:
59 return o
60
Raymond Hettinger7ac60952008-02-05 01:15:57 +000061 def __delitem__(self, key):
62 del self.data[key]
63
64 def __len__(self):
65 return sum(wr() is not None for wr in self.data.values())
66
Raymond Hettinger61146792004-08-19 21:32:06 +000067 def __contains__(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):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000110 for wr in self.data.values():
Raymond Hettinger61146792004-08-19 21:32:06 +0000111 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):
Guido van Rossum07f24362007-02-11 22:59:48 +0000116 return iter(self.data.keys())
Raymond Hettinger61146792004-08-19 21:32:06 +0000117
118 def __iter__(self):
Guido van Rossum07f24362007-02-11 22:59:48 +0000119 return iter(self.data.keys())
Fred Drake101209d2001-05-02 05:43:09 +0000120
Thomas Wouters477c8d52006-05-27 19:21:47 +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 """
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000131 return self.data.values()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132
Fred Drake101209d2001-05-02 05:43:09 +0000133 def itervalues(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000134 for wr in self.data.values():
Raymond Hettinger61146792004-08-19 21:32:06 +0000135 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:
Collin Winterce36ad82007-08-30 01:19:48 +0000154 raise KeyError(key)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000155 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
Thomas Wouters477c8d52006-05-27 19:21:47 +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
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000197collections.MutableMapping.register(WeakValueDictionary)
Fred Drake0a4dd392004-07-02 18:57:45 +0000198
199class KeyedRef(ref):
200 """Specialized reference that includes a key corresponding to the value.
201
202 This is used in the WeakValueDictionary to avoid having to create
203 a function object for each key stored in the mapping. A shared
204 callback object can use the 'key' attribute of a KeyedRef instead
205 of getting a reference to the key from an enclosing scope.
206
207 """
208
209 __slots__ = "key",
210
211 def __new__(type, ob, callback, key):
212 self = ref.__new__(type, ob, callback)
213 self.key = key
214 return self
215
216 def __init__(self, ob, callback, key):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000217 super().__init__(ob, callback)
Fred Drake746fe0f2001-09-28 19:01:26 +0000218
Fred Drake41deb1e2001-02-01 05:27:45 +0000219
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000220class WeakKeyDictionary(collections.MutableMapping):
Fred Drakebd7f8182001-04-19 16:26:06 +0000221 """ Mapping class that references keys weakly.
222
223 Entries in the dictionary will be discarded when there is no
224 longer a strong reference to the key. This can be used to
225 associate additional data with an object owned by other parts of
226 an application without adding attributes to those objects. This
227 can be especially useful with objects that override attribute
228 accesses.
229 """
Martin v. Löwis5e163332001-02-27 18:36:56 +0000230
231 def __init__(self, dict=None):
232 self.data = {}
Fred Drake746fe0f2001-09-28 19:01:26 +0000233 def remove(k, selfref=ref(self)):
234 self = selfref()
235 if self is not None:
236 del self.data[k]
Martin v. Löwis5e163332001-02-27 18:36:56 +0000237 self._remove = remove
Guido van Rossum009afb72002-06-10 20:00:52 +0000238 if dict is not None: self.update(dict)
Martin v. Löwis5e163332001-02-27 18:36:56 +0000239
Fred Drakeb663a2c2001-09-06 14:51:01 +0000240 def __delitem__(self, key):
Tim Peters886128f2003-05-25 01:45:11 +0000241 del self.data[ref(key)]
Fred Drakeb663a2c2001-09-06 14:51:01 +0000242
Martin v. Löwis5e163332001-02-27 18:36:56 +0000243 def __getitem__(self, key):
244 return self.data[ref(key)]
245
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000246 def __len__(self):
247 return len(self.data)
248
Martin v. Löwis5e163332001-02-27 18:36:56 +0000249 def __repr__(self):
250 return "<WeakKeyDictionary at %s>" % id(self)
251
252 def __setitem__(self, key, value):
253 self.data[ref(key, self._remove)] = value
254
255 def copy(self):
256 new = WeakKeyDictionary()
257 for key, value in self.data.items():
258 o = key()
259 if o is not None:
260 new[o] = value
Fred Drake9d2c85d2001-03-01 03:06:03 +0000261 return new
Martin v. Löwis5e163332001-02-27 18:36:56 +0000262
Fred Drake1d9e4b72001-04-16 17:34:48 +0000263 def get(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000264 return self.data.get(ref(key),default)
265
Raymond Hettinger54f02222002-06-01 14:18:47 +0000266 def __contains__(self, key):
267 try:
268 wr = ref(key)
269 except TypeError:
270 return 0
271 return wr in self.data
Tim Petersc411dba2002-07-16 21:35:23 +0000272
Martin v. Löwis5e163332001-02-27 18:36:56 +0000273 def items(self):
274 L = []
275 for key, value in self.data.items():
276 o = key()
277 if o is not None:
278 L.append((o, value))
279 return L
280
Fred Drake101209d2001-05-02 05:43:09 +0000281 def iteritems(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000282 for wr, value in self.data.items():
Raymond Hettinger61146792004-08-19 21:32:06 +0000283 key = wr()
284 if key is not None:
285 yield key, value
Fred Drake101209d2001-05-02 05:43:09 +0000286
Thomas Wouters477c8d52006-05-27 19:21:47 +0000287 def iterkeyrefs(self):
288 """Return an iterator that yields the weak references to the keys.
289
290 The references are not guaranteed to be 'live' at the time
291 they are used, so the result of calling the references needs
292 to be checked before being used. This can be used to avoid
293 creating references that will cause the garbage collector to
294 keep the keys around longer than needed.
295
296 """
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000297 return self.data.keys()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000298
Fred Drake101209d2001-05-02 05:43:09 +0000299 def iterkeys(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000300 for wr in self.data.keys():
Raymond Hettinger61146792004-08-19 21:32:06 +0000301 obj = wr()
302 if obj is not None:
303 yield obj
304
305 def __iter__(self):
Guido van Rossum07f24362007-02-11 22:59:48 +0000306 return iter(self.keys())
Fred Drake101209d2001-05-02 05:43:09 +0000307
308 def itervalues(self):
Guido van Rossum07f24362007-02-11 22:59:48 +0000309 return iter(self.data.values())
Fred Drake101209d2001-05-02 05:43:09 +0000310
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311 def keyrefs(self):
312 """Return a list of weak references to the keys.
313
314 The references are not guaranteed to be 'live' at the time
315 they are used, so the result of calling the references needs
316 to be checked before being used. This can be used to avoid
317 creating references that will cause the garbage collector to
318 keep the keys around longer than needed.
319
320 """
321 return self.data.keys()
322
Fred Drake1d9e4b72001-04-16 17:34:48 +0000323 def keys(self):
324 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000325 for wr in self.data.keys():
326 o = wr()
Fred Drake1d9e4b72001-04-16 17:34:48 +0000327 if o is not None:
328 L.append(o)
329 return L
330
Martin v. Löwis5e163332001-02-27 18:36:56 +0000331 def popitem(self):
332 while 1:
333 key, value = self.data.popitem()
334 o = key()
335 if o is not None:
336 return o, value
337
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000338 def pop(self, key, *args):
339 return self.data.pop(ref(key), *args)
340
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000341 def setdefault(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000342 return self.data.setdefault(ref(key, self._remove),default)
343
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000344 def update(self, dict=None, **kwargs):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000345 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000346 if dict is not None:
347 if not hasattr(dict, "items"):
348 dict = type({})(dict)
349 for key, value in dict.items():
350 d[ref(key, self._remove)] = value
351 if len(kwargs):
352 self.update(kwargs)
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000353
354collections.MutableMapping.register(WeakKeyDictionary)