blob: 64d962c351ff332b395679bb2b6a683980fd016b [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
Christian Heimes81ee3ef2008-05-04 22:42:01 +00005http://www.python.org/dev/peps/pep-0205/
Fred Drake41deb1e2001-02-01 05:27:45 +00006"""
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
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):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000216 super().__init__(ob, callback)
Fred Drake746fe0f2001-09-28 19:01:26 +0000217
Fred Drake41deb1e2001-02-01 05:27:45 +0000218
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000219class WeakKeyDictionary(collections.MutableMapping):
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
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000245 def __len__(self):
246 return len(self.data)
247
Martin v. Löwis5e163332001-02-27 18:36:56 +0000248 def __repr__(self):
249 return "<WeakKeyDictionary at %s>" % id(self)
250
251 def __setitem__(self, key, value):
252 self.data[ref(key, self._remove)] = value
253
254 def copy(self):
255 new = WeakKeyDictionary()
256 for key, value in self.data.items():
257 o = key()
258 if o is not None:
259 new[o] = value
Fred Drake9d2c85d2001-03-01 03:06:03 +0000260 return new
Martin v. Löwis5e163332001-02-27 18:36:56 +0000261
Fred Drake1d9e4b72001-04-16 17:34:48 +0000262 def get(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000263 return self.data.get(ref(key),default)
264
Raymond Hettinger54f02222002-06-01 14:18:47 +0000265 def __contains__(self, key):
266 try:
267 wr = ref(key)
268 except TypeError:
269 return 0
270 return wr in self.data
Tim Petersc411dba2002-07-16 21:35:23 +0000271
Martin v. Löwis5e163332001-02-27 18:36:56 +0000272 def items(self):
273 L = []
274 for key, value in self.data.items():
275 o = key()
276 if o is not None:
277 L.append((o, value))
278 return L
279
Fred Drake101209d2001-05-02 05:43:09 +0000280 def iteritems(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000281 for wr, value in self.data.items():
Raymond Hettinger61146792004-08-19 21:32:06 +0000282 key = wr()
283 if key is not None:
284 yield key, value
Fred Drake101209d2001-05-02 05:43:09 +0000285
Thomas Wouters477c8d52006-05-27 19:21:47 +0000286 def iterkeyrefs(self):
287 """Return an iterator that yields the weak references to the keys.
288
289 The references are not guaranteed to be 'live' at the time
290 they are used, so the result of calling the references needs
291 to be checked before being used. This can be used to avoid
292 creating references that will cause the garbage collector to
293 keep the keys around longer than needed.
294
295 """
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000296 return self.data.keys()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000297
Fred Drake101209d2001-05-02 05:43:09 +0000298 def iterkeys(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000299 for wr in self.data.keys():
Raymond Hettinger61146792004-08-19 21:32:06 +0000300 obj = wr()
301 if obj is not None:
302 yield obj
303
304 def __iter__(self):
Guido van Rossum07f24362007-02-11 22:59:48 +0000305 return iter(self.keys())
Fred Drake101209d2001-05-02 05:43:09 +0000306
307 def itervalues(self):
Guido van Rossum07f24362007-02-11 22:59:48 +0000308 return iter(self.data.values())
Fred Drake101209d2001-05-02 05:43:09 +0000309
Thomas Wouters477c8d52006-05-27 19:21:47 +0000310 def keyrefs(self):
311 """Return a list of weak references to the keys.
312
313 The references are not guaranteed to be 'live' at the time
314 they are used, so the result of calling the references needs
315 to be checked before being used. This can be used to avoid
316 creating references that will cause the garbage collector to
317 keep the keys around longer than needed.
318
319 """
320 return self.data.keys()
321
Fred Drake1d9e4b72001-04-16 17:34:48 +0000322 def keys(self):
323 L = []
Fred Drakebd7f8182001-04-19 16:26:06 +0000324 for wr in self.data.keys():
325 o = wr()
Fred Drake1d9e4b72001-04-16 17:34:48 +0000326 if o is not None:
327 L.append(o)
328 return L
329
Martin v. Löwis5e163332001-02-27 18:36:56 +0000330 def popitem(self):
331 while 1:
332 key, value = self.data.popitem()
333 o = key()
334 if o is not None:
335 return o, value
336
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000337 def pop(self, key, *args):
338 return self.data.pop(ref(key), *args)
339
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000340 def setdefault(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000341 return self.data.setdefault(ref(key, self._remove),default)
342
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000343 def update(self, dict=None, **kwargs):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000344 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000345 if dict is not None:
346 if not hasattr(dict, "items"):
347 dict = type({})(dict)
348 for key, value in dict.items():
349 d[ref(key, self._remove)] = value
350 if len(kwargs):
351 self.update(kwargs)