summaryrefslogtreecommitdiff
path: root/AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py
diff options
context:
space:
mode:
Diffstat (limited to 'AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py')
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py443
1 files changed, 443 insertions, 0 deletions
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py b/AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py
new file mode 100644
index 0000000000..dc6dbf050b
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Lib/weakref.py
@@ -0,0 +1,443 @@
+"""Weak reference support for Python.
+
+This module is an implementation of PEP 205:
+
+http://www.python.org/dev/peps/pep-0205/
+"""
+
+# Naming convention: Variables named "wr" are weak reference objects;
+# they are called this instead of "ref" to avoid name collisions with
+# the module-global ref() function imported from _weakref.
+
+import UserDict
+
+from _weakref import (
+ getweakrefcount,
+ getweakrefs,
+ ref,
+ proxy,
+ CallableProxyType,
+ ProxyType,
+ ReferenceType)
+
+from _weakrefset import WeakSet, _IterationGuard
+
+from exceptions import ReferenceError
+
+
+ProxyTypes = (ProxyType, CallableProxyType)
+
+__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
+ "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType",
+ "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 'WeakSet']
+
+
+class WeakValueDictionary(UserDict.UserDict):
+ """Mapping class that references values weakly.
+
+ Entries in the dictionary will be discarded when no strong
+ reference to the value exists anymore
+ """
+ # We inherit the constructor without worrying about the input
+ # dictionary; since it uses our .update() method, we get the right
+ # checks (if the other dictionary is a WeakValueDictionary,
+ # objects are unwrapped on the way out, and we always wrap on the
+ # way in).
+
+ def __init__(self, *args, **kw):
+ def remove(wr, selfref=ref(self)):
+ self = selfref()
+ if self is not None:
+ if self._iterating:
+ self._pending_removals.append(wr.key)
+ else:
+ del self.data[wr.key]
+ self._remove = remove
+ # A list of keys to be removed
+ self._pending_removals = []
+ self._iterating = set()
+ UserDict.UserDict.__init__(self, *args, **kw)
+
+ def _commit_removals(self):
+ l = self._pending_removals
+ d = self.data
+ # We shouldn't encounter any KeyError, because this method should
+ # always be called *before* mutating the dict.
+ while l:
+ del d[l.pop()]
+
+ def __getitem__(self, key):
+ o = self.data[key]()
+ if o is None:
+ raise KeyError, key
+ else:
+ return o
+
+ def __delitem__(self, key):
+ if self._pending_removals:
+ self._commit_removals()
+ del self.data[key]
+
+ def __contains__(self, key):
+ try:
+ o = self.data[key]()
+ except KeyError:
+ return False
+ return o is not None
+
+ def has_key(self, key):
+ try:
+ o = self.data[key]()
+ except KeyError:
+ return False
+ return o is not None
+
+ def __repr__(self):
+ return "<WeakValueDictionary at %s>" % id(self)
+
+ def __setitem__(self, key, value):
+ if self._pending_removals:
+ self._commit_removals()
+ self.data[key] = KeyedRef(value, self._remove, key)
+
+ def clear(self):
+ if self._pending_removals:
+ self._commit_removals()
+ self.data.clear()
+
+ def copy(self):
+ new = WeakValueDictionary()
+ for key, wr in self.data.items():
+ o = wr()
+ if o is not None:
+ new[key] = o
+ return new
+
+ __copy__ = copy
+
+ def __deepcopy__(self, memo):
+ from copy import deepcopy
+ new = self.__class__()
+ for key, wr in self.data.items():
+ o = wr()
+ if o is not None:
+ new[deepcopy(key, memo)] = o
+ return new
+
+ def get(self, key, default=None):
+ try:
+ wr = self.data[key]
+ except KeyError:
+ return default
+ else:
+ o = wr()
+ if o is None:
+ # This should only happen
+ return default
+ else:
+ return o
+
+ def items(self):
+ L = []
+ for key, wr in self.data.items():
+ o = wr()
+ if o is not None:
+ L.append((key, o))
+ return L
+
+ def iteritems(self):
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ value = wr()
+ if value is not None:
+ yield wr.key, value
+
+ def iterkeys(self):
+ with _IterationGuard(self):
+ for k in self.data.iterkeys():
+ yield k
+
+ __iter__ = iterkeys
+
+ def itervaluerefs(self):
+ """Return an iterator that yields the weak references to the values.
+
+ The references are not guaranteed to be 'live' at the time
+ they are used, so the result of calling the references needs
+ to be checked before being used. This can be used to avoid
+ creating references that will cause the garbage collector to
+ keep the values around longer than needed.
+
+ """
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ yield wr
+
+ def itervalues(self):
+ with _IterationGuard(self):
+ for wr in self.data.itervalues():
+ obj = wr()
+ if obj is not None:
+ yield obj
+
+ def popitem(self):
+ if self._pending_removals:
+ self._commit_removals()
+ while 1:
+ key, wr = self.data.popitem()
+ o = wr()
+ if o is not None:
+ return key, o
+
+ def pop(self, key, *args):
+ if self._pending_removals:
+ self._commit_removals()
+ try:
+ o = self.data.pop(key)()
+ except KeyError:
+ if args:
+ return args[0]
+ raise
+ if o is None:
+ raise KeyError, key
+ else:
+ return o
+
+ def setdefault(self, key, default=None):
+ try:
+ wr = self.data[key]
+ except KeyError:
+ if self._pending_removals:
+ self._commit_removals()
+ self.data[key] = KeyedRef(default, self._remove, key)
+ return default
+ else:
+ return wr()
+
+ def update(self, dict=None, **kwargs):
+ if self._pending_removals:
+ self._commit_removals()
+ d = self.data
+ if dict is not None:
+ if not hasattr(dict, "items"):
+ dict = type({})(dict)
+ for key, o in dict.items():
+ d[key] = KeyedRef(o, self._remove, key)
+ if len(kwargs):
+ self.update(kwargs)
+
+ def valuerefs(self):
+ """Return a list of weak references to the values.
+
+ The references are not guaranteed to be 'live' at the time
+ they are used, so the result of calling the references needs
+ to be checked before being used. This can be used to avoid
+ creating references that will cause the garbage collector to
+ keep the values around longer than needed.
+
+ """
+ return self.data.values()
+
+ def values(self):
+ L = []
+ for wr in self.data.values():
+ o = wr()
+ if o is not None:
+ L.append(o)
+ return L
+
+
+class KeyedRef(ref):
+ """Specialized reference that includes a key corresponding to the value.
+
+ This is used in the WeakValueDictionary to avoid having to create
+ a function object for each key stored in the mapping. A shared
+ callback object can use the 'key' attribute of a KeyedRef instead
+ of getting a reference to the key from an enclosing scope.
+
+ """
+
+ __slots__ = "key",
+
+ def __new__(type, ob, callback, key):
+ self = ref.__new__(type, ob, callback)
+ self.key = key
+ return self
+
+ def __init__(self, ob, callback, key):
+ super(KeyedRef, self).__init__(ob, callback)
+
+
+class WeakKeyDictionary(UserDict.UserDict):
+ """ Mapping class that references keys weakly.
+
+ Entries in the dictionary will be discarded when there is no
+ longer a strong reference to the key. This can be used to
+ associate additional data with an object owned by other parts of
+ an application without adding attributes to those objects. This
+ can be especially useful with objects that override attribute
+ accesses.
+ """
+
+ def __init__(self, dict=None):
+ self.data = {}
+ def remove(k, selfref=ref(self)):
+ self = selfref()
+ if self is not None:
+ if self._iterating:
+ self._pending_removals.append(k)
+ else:
+ del self.data[k]
+ self._remove = remove
+ # A list of dead weakrefs (keys to be removed)
+ self._pending_removals = []
+ self._iterating = set()
+ if dict is not None:
+ self.update(dict)
+
+ def _commit_removals(self):
+ # NOTE: We don't need to call this method before mutating the dict,
+ # because a dead weakref never compares equal to a live weakref,
+ # even if they happened to refer to equal objects.
+ # However, it means keys may already have been removed.
+ l = self._pending_removals
+ d = self.data
+ while l:
+ try:
+ del d[l.pop()]
+ except KeyError:
+ pass
+
+ def __delitem__(self, key):
+ del self.data[ref(key)]
+
+ def __getitem__(self, key):
+ return self.data[ref(key)]
+
+ def __repr__(self):
+ return "<WeakKeyDictionary at %s>" % id(self)
+
+ def __setitem__(self, key, value):
+ self.data[ref(key, self._remove)] = value
+
+ def copy(self):
+ new = WeakKeyDictionary()
+ for key, value in self.data.items():
+ o = key()
+ if o is not None:
+ new[o] = value
+ return new
+
+ __copy__ = copy
+
+ def __deepcopy__(self, memo):
+ from copy import deepcopy
+ new = self.__class__()
+ for key, value in self.data.items():
+ o = key()
+ if o is not None:
+ new[o] = deepcopy(value, memo)
+ return new
+
+ def get(self, key, default=None):
+ return self.data.get(ref(key),default)
+
+ def has_key(self, key):
+ try:
+ wr = ref(key)
+ except TypeError:
+ return 0
+ return wr in self.data
+
+ def __contains__(self, key):
+ try:
+ wr = ref(key)
+ except TypeError:
+ return 0
+ return wr in self.data
+
+ def items(self):
+ L = []
+ for key, value in self.data.items():
+ o = key()
+ if o is not None:
+ L.append((o, value))
+ return L
+
+ def iteritems(self):
+ with _IterationGuard(self):
+ for wr, value in self.data.iteritems():
+ key = wr()
+ if key is not None:
+ yield key, value
+
+ def iterkeyrefs(self):
+ """Return an iterator that yields the weak references to the keys.
+
+ The references are not guaranteed to be 'live' at the time
+ they are used, so the result of calling the references needs
+ to be checked before being used. This can be used to avoid
+ creating references that will cause the garbage collector to
+ keep the keys around longer than needed.
+
+ """
+ with _IterationGuard(self):
+ for wr in self.data.iterkeys():
+ yield wr
+
+ def iterkeys(self):
+ with _IterationGuard(self):
+ for wr in self.data.iterkeys():
+ obj = wr()
+ if obj is not None:
+ yield obj
+
+ __iter__ = iterkeys
+
+ def itervalues(self):
+ with _IterationGuard(self):
+ for value in self.data.itervalues():
+ yield value
+
+ def keyrefs(self):
+ """Return a list of weak references to the keys.
+
+ The references are not guaranteed to be 'live' at the time
+ they are used, so the result of calling the references needs
+ to be checked before being used. This can be used to avoid
+ creating references that will cause the garbage collector to
+ keep the keys around longer than needed.
+
+ """
+ return self.data.keys()
+
+ def keys(self):
+ L = []
+ for wr in self.data.keys():
+ o = wr()
+ if o is not None:
+ L.append(o)
+ return L
+
+ def popitem(self):
+ while 1:
+ key, value = self.data.popitem()
+ o = key()
+ if o is not None:
+ return o, value
+
+ def pop(self, key, *args):
+ return self.data.pop(ref(key), *args)
+
+ def setdefault(self, key, default=None):
+ return self.data.setdefault(ref(key, self._remove),default)
+
+ def update(self, dict=None, **kwargs):
+ d = self.data
+ if dict is not None:
+ if not hasattr(dict, "items"):
+ dict = type({})(dict)
+ for key, value in dict.items():
+ d[ref(key, self._remove)] = value
+ if len(kwargs):
+ self.update(kwargs)