1 """Weak reference support for Python.
3 This module is an implementation of PEP 205:
5 http://www.python.org/dev/peps/pep-0205/
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.
14 from _weakref
import (
23 from _weakrefset
import WeakSet
25 from exceptions
import ReferenceError
28 ProxyTypes
= (ProxyType
, CallableProxyType
)
30 __all__
= ["ref", "proxy", "getweakrefcount", "getweakrefs",
31 "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType",
32 "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 'WeakSet']
35 class WeakValueDictionary(UserDict
.UserDict
):
36 """Mapping class that references values weakly.
38 Entries in the dictionary will be discarded when no strong
39 reference to the value exists anymore
41 # We inherit the constructor without worrying about the input
42 # dictionary; since it uses our .update() method, we get the right
43 # checks (if the other dictionary is a WeakValueDictionary,
44 # objects are unwrapped on the way out, and we always wrap on the
47 def __init__(self
, *args
, **kw
):
48 def remove(wr
, selfref
=ref(self
)):
53 UserDict
.UserDict
.__init
__(self
, *args
, **kw
)
55 def __getitem__(self
, key
):
62 def __contains__(self
, key
):
69 def has_key(self
, key
):
77 return "<WeakValueDictionary at %s>" % id(self
)
79 def __setitem__(self
, key
, value
):
80 self
.data
[key
] = KeyedRef(value
, self
._remove
, key
)
83 new
= WeakValueDictionary()
84 for key
, wr
in self
.data
.items():
92 def __deepcopy__(self
, memo
):
93 from copy
import deepcopy
94 new
= self
.__class
__()
95 for key
, wr
in self
.data
.items():
98 new
[deepcopy(key
, memo
)] = o
101 def get(self
, key
, default
=None):
109 # This should only happen
116 for key
, wr
in self
.data
.items():
123 for wr
in self
.data
.itervalues():
125 if value
is not None:
129 return self
.data
.iterkeys()
132 return self
.data
.iterkeys()
134 def itervaluerefs(self
):
135 """Return an iterator that yields the weak references to the values.
137 The references are not guaranteed to be 'live' at the time
138 they are used, so the result of calling the references needs
139 to be checked before being used. This can be used to avoid
140 creating references that will cause the garbage collector to
141 keep the values around longer than needed.
144 return self
.data
.itervalues()
146 def itervalues(self
):
147 for wr
in self
.data
.itervalues():
154 key
, wr
= self
.data
.popitem()
159 def pop(self
, key
, *args
):
161 o
= self
.data
.pop(key
)()
171 def setdefault(self
, key
, default
=None):
175 self
.data
[key
] = KeyedRef(default
, self
._remove
, key
)
180 def update(self
, dict=None, **kwargs
):
183 if not hasattr(dict, "items"):
184 dict = type({})(dict)
185 for key
, o
in dict.items():
186 d
[key
] = KeyedRef(o
, self
._remove
, key
)
191 """Return a list of weak references to the values.
193 The references are not guaranteed to be 'live' at the time
194 they are used, so the result of calling the references needs
195 to be checked before being used. This can be used to avoid
196 creating references that will cause the garbage collector to
197 keep the values around longer than needed.
200 return self
.data
.values()
204 for wr
in self
.data
.values():
212 """Specialized reference that includes a key corresponding to the value.
214 This is used in the WeakValueDictionary to avoid having to create
215 a function object for each key stored in the mapping. A shared
216 callback object can use the 'key' attribute of a KeyedRef instead
217 of getting a reference to the key from an enclosing scope.
223 def __new__(type, ob
, callback
, key
):
224 self
= ref
.__new
__(type, ob
, callback
)
228 def __init__(self
, ob
, callback
, key
):
229 super(KeyedRef
, self
).__init
__(ob
, callback
)
232 class WeakKeyDictionary(UserDict
.UserDict
):
233 """ Mapping class that references keys weakly.
235 Entries in the dictionary will be discarded when there is no
236 longer a strong reference to the key. This can be used to
237 associate additional data with an object owned by other parts of
238 an application without adding attributes to those objects. This
239 can be especially useful with objects that override attribute
243 def __init__(self
, dict=None):
245 def remove(k
, selfref
=ref(self
)):
249 self
._remove
= remove
250 if dict is not None: self
.update(dict)
252 def __delitem__(self
, key
):
253 del self
.data
[ref(key
)]
255 def __getitem__(self
, key
):
256 return self
.data
[ref(key
)]
259 return "<WeakKeyDictionary at %s>" % id(self
)
261 def __setitem__(self
, key
, value
):
262 self
.data
[ref(key
, self
._remove
)] = value
265 new
= WeakKeyDictionary()
266 for key
, value
in self
.data
.items():
274 def __deepcopy__(self
, memo
):
275 from copy
import deepcopy
276 new
= self
.__class
__()
277 for key
, value
in self
.data
.items():
280 new
[o
] = deepcopy(value
, memo
)
283 def get(self
, key
, default
=None):
284 return self
.data
.get(ref(key
),default
)
286 def has_key(self
, key
):
291 return wr
in self
.data
293 def __contains__(self
, key
):
298 return wr
in self
.data
302 for key
, value
in self
.data
.items():
309 for wr
, value
in self
.data
.iteritems():
314 def iterkeyrefs(self
):
315 """Return an iterator that yields the weak references to the keys.
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.
324 return self
.data
.iterkeys()
327 for wr
in self
.data
.iterkeys():
333 return self
.iterkeys()
335 def itervalues(self
):
336 return self
.data
.itervalues()
339 """Return a list of weak references to the keys.
341 The references are not guaranteed to be 'live' at the time
342 they are used, so the result of calling the references needs
343 to be checked before being used. This can be used to avoid
344 creating references that will cause the garbage collector to
345 keep the keys around longer than needed.
348 return self
.data
.keys()
352 for wr
in self
.data
.keys():
360 key
, value
= self
.data
.popitem()
365 def pop(self
, key
, *args
):
366 return self
.data
.pop(ref(key
), *args
)
368 def setdefault(self
, key
, default
=None):
369 return self
.data
.setdefault(ref(key
, self
._remove
),default
)
371 def update(self
, dict=None, **kwargs
):
374 if not hasattr(dict, "items"):
375 dict = type({})(dict)
376 for key
, value
in dict.items():
377 d
[ref(key
, self
._remove
)] = value