]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Lib / weakref.py
1 """Weak reference support for Python.
2
3 This module is an implementation of PEP 205:
4
5 http://www.python.org/dev/peps/pep-0205/
6 """
7
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.
11
12 import UserDict
13
14 from _weakref import (
15 getweakrefcount,
16 getweakrefs,
17 ref,
18 proxy,
19 CallableProxyType,
20 ProxyType,
21 ReferenceType)
22
23 from _weakrefset import WeakSet, _IterationGuard
24
25 from exceptions import ReferenceError
26
27
28 ProxyTypes = (ProxyType, CallableProxyType)
29
30 __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
31 "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType",
32 "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 'WeakSet']
33
34
35 class WeakValueDictionary(UserDict.UserDict):
36 """Mapping class that references values weakly.
37
38 Entries in the dictionary will be discarded when no strong
39 reference to the value exists anymore
40 """
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
45 # way in).
46
47 def __init__(self, *args, **kw):
48 def remove(wr, selfref=ref(self)):
49 self = selfref()
50 if self is not None:
51 if self._iterating:
52 self._pending_removals.append(wr.key)
53 else:
54 del self.data[wr.key]
55 self._remove = remove
56 # A list of keys to be removed
57 self._pending_removals = []
58 self._iterating = set()
59 UserDict.UserDict.__init__(self, *args, **kw)
60
61 def _commit_removals(self):
62 l = self._pending_removals
63 d = self.data
64 # We shouldn't encounter any KeyError, because this method should
65 # always be called *before* mutating the dict.
66 while l:
67 del d[l.pop()]
68
69 def __getitem__(self, key):
70 o = self.data[key]()
71 if o is None:
72 raise KeyError, key
73 else:
74 return o
75
76 def __delitem__(self, key):
77 if self._pending_removals:
78 self._commit_removals()
79 del self.data[key]
80
81 def __contains__(self, key):
82 try:
83 o = self.data[key]()
84 except KeyError:
85 return False
86 return o is not None
87
88 def has_key(self, key):
89 try:
90 o = self.data[key]()
91 except KeyError:
92 return False
93 return o is not None
94
95 def __repr__(self):
96 return "<WeakValueDictionary at %s>" % id(self)
97
98 def __setitem__(self, key, value):
99 if self._pending_removals:
100 self._commit_removals()
101 self.data[key] = KeyedRef(value, self._remove, key)
102
103 def clear(self):
104 if self._pending_removals:
105 self._commit_removals()
106 self.data.clear()
107
108 def copy(self):
109 new = WeakValueDictionary()
110 for key, wr in self.data.items():
111 o = wr()
112 if o is not None:
113 new[key] = o
114 return new
115
116 __copy__ = copy
117
118 def __deepcopy__(self, memo):
119 from copy import deepcopy
120 new = self.__class__()
121 for key, wr in self.data.items():
122 o = wr()
123 if o is not None:
124 new[deepcopy(key, memo)] = o
125 return new
126
127 def get(self, key, default=None):
128 try:
129 wr = self.data[key]
130 except KeyError:
131 return default
132 else:
133 o = wr()
134 if o is None:
135 # This should only happen
136 return default
137 else:
138 return o
139
140 def items(self):
141 L = []
142 for key, wr in self.data.items():
143 o = wr()
144 if o is not None:
145 L.append((key, o))
146 return L
147
148 def iteritems(self):
149 with _IterationGuard(self):
150 for wr in self.data.itervalues():
151 value = wr()
152 if value is not None:
153 yield wr.key, value
154
155 def iterkeys(self):
156 with _IterationGuard(self):
157 for k in self.data.iterkeys():
158 yield k
159
160 __iter__ = iterkeys
161
162 def itervaluerefs(self):
163 """Return an iterator that yields the weak references to the values.
164
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.
170
171 """
172 with _IterationGuard(self):
173 for wr in self.data.itervalues():
174 yield wr
175
176 def itervalues(self):
177 with _IterationGuard(self):
178 for wr in self.data.itervalues():
179 obj = wr()
180 if obj is not None:
181 yield obj
182
183 def popitem(self):
184 if self._pending_removals:
185 self._commit_removals()
186 while 1:
187 key, wr = self.data.popitem()
188 o = wr()
189 if o is not None:
190 return key, o
191
192 def pop(self, key, *args):
193 if self._pending_removals:
194 self._commit_removals()
195 try:
196 o = self.data.pop(key)()
197 except KeyError:
198 if args:
199 return args[0]
200 raise
201 if o is None:
202 raise KeyError, key
203 else:
204 return o
205
206 def setdefault(self, key, default=None):
207 try:
208 wr = self.data[key]
209 except KeyError:
210 if self._pending_removals:
211 self._commit_removals()
212 self.data[key] = KeyedRef(default, self._remove, key)
213 return default
214 else:
215 return wr()
216
217 def update(self, dict=None, **kwargs):
218 if self._pending_removals:
219 self._commit_removals()
220 d = self.data
221 if dict is not None:
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)
226 if len(kwargs):
227 self.update(kwargs)
228
229 def valuerefs(self):
230 """Return a list of weak references to the values.
231
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.
237
238 """
239 return self.data.values()
240
241 def values(self):
242 L = []
243 for wr in self.data.values():
244 o = wr()
245 if o is not None:
246 L.append(o)
247 return L
248
249
250 class KeyedRef(ref):
251 """Specialized reference that includes a key corresponding to the value.
252
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.
257
258 """
259
260 __slots__ = "key",
261
262 def __new__(type, ob, callback, key):
263 self = ref.__new__(type, ob, callback)
264 self.key = key
265 return self
266
267 def __init__(self, ob, callback, key):
268 super(KeyedRef, self).__init__(ob, callback)
269
270
271 class WeakKeyDictionary(UserDict.UserDict):
272 """ Mapping class that references keys weakly.
273
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
279 accesses.
280 """
281
282 def __init__(self, dict=None):
283 self.data = {}
284 def remove(k, selfref=ref(self)):
285 self = selfref()
286 if self is not None:
287 if self._iterating:
288 self._pending_removals.append(k)
289 else:
290 del self.data[k]
291 self._remove = remove
292 # A list of dead weakrefs (keys to be removed)
293 self._pending_removals = []
294 self._iterating = set()
295 if dict is not None:
296 self.update(dict)
297
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
304 d = self.data
305 while l:
306 try:
307 del d[l.pop()]
308 except KeyError:
309 pass
310
311 def __delitem__(self, key):
312 del self.data[ref(key)]
313
314 def __getitem__(self, key):
315 return self.data[ref(key)]
316
317 def __repr__(self):
318 return "<WeakKeyDictionary at %s>" % id(self)
319
320 def __setitem__(self, key, value):
321 self.data[ref(key, self._remove)] = value
322
323 def copy(self):
324 new = WeakKeyDictionary()
325 for key, value in self.data.items():
326 o = key()
327 if o is not None:
328 new[o] = value
329 return new
330
331 __copy__ = copy
332
333 def __deepcopy__(self, memo):
334 from copy import deepcopy
335 new = self.__class__()
336 for key, value in self.data.items():
337 o = key()
338 if o is not None:
339 new[o] = deepcopy(value, memo)
340 return new
341
342 def get(self, key, default=None):
343 return self.data.get(ref(key),default)
344
345 def has_key(self, key):
346 try:
347 wr = ref(key)
348 except TypeError:
349 return 0
350 return wr in self.data
351
352 def __contains__(self, key):
353 try:
354 wr = ref(key)
355 except TypeError:
356 return 0
357 return wr in self.data
358
359 def items(self):
360 L = []
361 for key, value in self.data.items():
362 o = key()
363 if o is not None:
364 L.append((o, value))
365 return L
366
367 def iteritems(self):
368 with _IterationGuard(self):
369 for wr, value in self.data.iteritems():
370 key = wr()
371 if key is not None:
372 yield key, value
373
374 def iterkeyrefs(self):
375 """Return an iterator that yields the weak references to the keys.
376
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.
382
383 """
384 with _IterationGuard(self):
385 for wr in self.data.iterkeys():
386 yield wr
387
388 def iterkeys(self):
389 with _IterationGuard(self):
390 for wr in self.data.iterkeys():
391 obj = wr()
392 if obj is not None:
393 yield obj
394
395 __iter__ = iterkeys
396
397 def itervalues(self):
398 with _IterationGuard(self):
399 for value in self.data.itervalues():
400 yield value
401
402 def keyrefs(self):
403 """Return a list of weak references to the keys.
404
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.
410
411 """
412 return self.data.keys()
413
414 def keys(self):
415 L = []
416 for wr in self.data.keys():
417 o = wr()
418 if o is not None:
419 L.append(o)
420 return L
421
422 def popitem(self):
423 while 1:
424 key, value = self.data.popitem()
425 o = key()
426 if o is not None:
427 return o, value
428
429 def pop(self, key, *args):
430 return self.data.pop(ref(key), *args)
431
432 def setdefault(self, key, default=None):
433 return self.data.setdefault(ref(key, self._remove),default)
434
435 def update(self, dict=None, **kwargs):
436 d = self.data
437 if dict is not None:
438 if not hasattr(dict, "items"):
439 dict = type({})(dict)
440 for key, value in dict.items():
441 d[ref(key, self._remove)] = value
442 if len(kwargs):
443 self.update(kwargs)