]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py
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
, _IterationGuard
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
)):
52 self
._pending
_removals
.append(wr
.key
)
56 # A list of keys to be removed
57 self
._pending
_removals
= []
58 self
._iterating
= set()
59 UserDict
.UserDict
.__init
__(self
, *args
, **kw
)
61 def _commit_removals(self
):
62 l
= self
._pending
_removals
64 # We shouldn't encounter any KeyError, because this method should
65 # always be called *before* mutating the dict.
69 def __getitem__(self
, key
):
76 def __delitem__(self
, key
):
77 if self
._pending
_removals
:
78 self
._commit
_removals
()
81 def __contains__(self
, key
):
88 def has_key(self
, key
):
96 return "<WeakValueDictionary at %s>" % id(self
)
98 def __setitem__(self
, key
, value
):
99 if self
._pending
_removals
:
100 self
._commit
_removals
()
101 self
.data
[key
] = KeyedRef(value
, self
._remove
, key
)
104 if self
._pending
_removals
:
105 self
._commit
_removals
()
109 new
= WeakValueDictionary()
110 for key
, wr
in self
.data
.items():
118 def __deepcopy__(self
, memo
):
119 from copy
import deepcopy
120 new
= self
.__class
__()
121 for key
, wr
in self
.data
.items():
124 new
[deepcopy(key
, memo
)] = o
127 def get(self
, key
, default
=None):
135 # This should only happen
142 for key
, wr
in self
.data
.items():
149 with
_IterationGuard(self
):
150 for wr
in self
.data
.itervalues():
152 if value
is not None:
156 with
_IterationGuard(self
):
157 for k
in self
.data
.iterkeys():
162 def itervaluerefs(self
):
163 """Return an iterator that yields the weak references to the values.
165 The references are not guaranteed to be 'live' at the time
166 they are used, so the result of calling the references needs
167 to be checked before being used. This can be used to avoid
168 creating references that will cause the garbage collector to
169 keep the values around longer than needed.
172 with
_IterationGuard(self
):
173 for wr
in self
.data
.itervalues():
176 def itervalues(self
):
177 with
_IterationGuard(self
):
178 for wr
in self
.data
.itervalues():
184 if self
._pending
_removals
:
185 self
._commit
_removals
()
187 key
, wr
= self
.data
.popitem()
192 def pop(self
, key
, *args
):
193 if self
._pending
_removals
:
194 self
._commit
_removals
()
196 o
= self
.data
.pop(key
)()
206 def setdefault(self
, key
, default
=None):
210 if self
._pending
_removals
:
211 self
._commit
_removals
()
212 self
.data
[key
] = KeyedRef(default
, self
._remove
, key
)
217 def update(self
, dict=None, **kwargs
):
218 if self
._pending
_removals
:
219 self
._commit
_removals
()
222 if not hasattr(dict, "items"):
223 dict = type({})(dict)
224 for key
, o
in dict.items():
225 d
[key
] = KeyedRef(o
, self
._remove
, key
)
230 """Return a list of weak references to the values.
232 The references are not guaranteed to be 'live' at the time
233 they are used, so the result of calling the references needs
234 to be checked before being used. This can be used to avoid
235 creating references that will cause the garbage collector to
236 keep the values around longer than needed.
239 return self
.data
.values()
243 for wr
in self
.data
.values():
251 """Specialized reference that includes a key corresponding to the value.
253 This is used in the WeakValueDictionary to avoid having to create
254 a function object for each key stored in the mapping. A shared
255 callback object can use the 'key' attribute of a KeyedRef instead
256 of getting a reference to the key from an enclosing scope.
262 def __new__(type, ob
, callback
, key
):
263 self
= ref
.__new
__(type, ob
, callback
)
267 def __init__(self
, ob
, callback
, key
):
268 super(KeyedRef
, self
).__init
__(ob
, callback
)
271 class WeakKeyDictionary(UserDict
.UserDict
):
272 """ Mapping class that references keys weakly.
274 Entries in the dictionary will be discarded when there is no
275 longer a strong reference to the key. This can be used to
276 associate additional data with an object owned by other parts of
277 an application without adding attributes to those objects. This
278 can be especially useful with objects that override attribute
282 def __init__(self
, dict=None):
284 def remove(k
, selfref
=ref(self
)):
288 self
._pending
_removals
.append(k
)
291 self
._remove
= remove
292 # A list of dead weakrefs (keys to be removed)
293 self
._pending
_removals
= []
294 self
._iterating
= set()
298 def _commit_removals(self
):
299 # NOTE: We don't need to call this method before mutating the dict,
300 # because a dead weakref never compares equal to a live weakref,
301 # even if they happened to refer to equal objects.
302 # However, it means keys may already have been removed.
303 l
= self
._pending
_removals
311 def __delitem__(self
, key
):
312 del self
.data
[ref(key
)]
314 def __getitem__(self
, key
):
315 return self
.data
[ref(key
)]
318 return "<WeakKeyDictionary at %s>" % id(self
)
320 def __setitem__(self
, key
, value
):
321 self
.data
[ref(key
, self
._remove
)] = value
324 new
= WeakKeyDictionary()
325 for key
, value
in self
.data
.items():
333 def __deepcopy__(self
, memo
):
334 from copy
import deepcopy
335 new
= self
.__class
__()
336 for key
, value
in self
.data
.items():
339 new
[o
] = deepcopy(value
, memo
)
342 def get(self
, key
, default
=None):
343 return self
.data
.get(ref(key
),default
)
345 def has_key(self
, key
):
350 return wr
in self
.data
352 def __contains__(self
, key
):
357 return wr
in self
.data
361 for key
, value
in self
.data
.items():
368 with
_IterationGuard(self
):
369 for wr
, value
in self
.data
.iteritems():
374 def iterkeyrefs(self
):
375 """Return an iterator that yields the weak references to the keys.
377 The references are not guaranteed to be 'live' at the time
378 they are used, so the result of calling the references needs
379 to be checked before being used. This can be used to avoid
380 creating references that will cause the garbage collector to
381 keep the keys around longer than needed.
384 with
_IterationGuard(self
):
385 for wr
in self
.data
.iterkeys():
389 with
_IterationGuard(self
):
390 for wr
in self
.data
.iterkeys():
397 def itervalues(self
):
398 with
_IterationGuard(self
):
399 for value
in self
.data
.itervalues():
403 """Return a list of weak references to the keys.
405 The references are not guaranteed to be 'live' at the time
406 they are used, so the result of calling the references needs
407 to be checked before being used. This can be used to avoid
408 creating references that will cause the garbage collector to
409 keep the keys around longer than needed.
412 return self
.data
.keys()
416 for wr
in self
.data
.keys():
424 key
, value
= self
.data
.popitem()
429 def pop(self
, key
, *args
):
430 return self
.data
.pop(ref(key
), *args
)
432 def setdefault(self
, key
, default
=None):
433 return self
.data
.setdefault(ref(key
, self
._remove
),default
)
435 def update(self
, dict=None, **kwargs
):
438 if not hasattr(dict, "items"):
439 dict = type({})(dict)
440 for key
, value
in dict.items():
441 d
[ref(key
, self
._remove
)] = value