You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

weakref.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. """Weak reference support for Python.
  2. This module is an implementation of PEP 205:
  3. http://python.sourceforge.net/peps/pep-0205.html
  4. """
  5. import UserDict
  6. from _weakref import \
  7. getweakrefcount, \
  8. getweakrefs, \
  9. ref, \
  10. proxy, \
  11. ReferenceError, \
  12. CallableProxyType, \
  13. ProxyType, \
  14. ReferenceType
  15. ProxyTypes = (ProxyType, CallableProxyType)
  16. __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
  17. "WeakKeyDictionary", "ReferenceType", "ProxyType",
  18. "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
  19. class WeakValueDictionary(UserDict.UserDict):
  20. # We inherit the constructor without worrying about the input
  21. # dictionary; since it uses our .update() method, we get the right
  22. # checks (if the other dictionary is a WeakValueDictionary,
  23. # objects are unwrapped on the way out, and we always wrap on the
  24. # way in).
  25. def __getitem__(self, key):
  26. o = self.data.get(key)()
  27. if o is None:
  28. raise KeyError, key
  29. else:
  30. return o
  31. def __repr__(self):
  32. return "<WeakValueDictionary at %s>" % id(self)
  33. def __setitem__(self, key, value):
  34. def remove(o, data=self.data, key=key):
  35. del data[key]
  36. self.data[key] = ref(value, remove)
  37. def copy(self):
  38. new = WeakValueDictionary()
  39. for key, ref in self.data.items():
  40. o = ref()
  41. if o is not None:
  42. new[key] = o
  43. return new
  44. def get(self, key, default=None):
  45. try:
  46. ref = self.data[key]
  47. except KeyError:
  48. return default
  49. else:
  50. o = ref()
  51. if o is None:
  52. # This should only happen
  53. return default
  54. else:
  55. return o
  56. def items(self):
  57. L = []
  58. for key, ref in self.data.items():
  59. o = ref()
  60. if o is not None:
  61. L.append((key, o))
  62. return L
  63. def popitem(self):
  64. while 1:
  65. key, ref = self.data.popitem()
  66. o = ref()
  67. if o is not None:
  68. return key, o
  69. def setdefault(self, key, default):
  70. try:
  71. ref = self.data[key]
  72. except KeyError:
  73. def remove(o, data=self.data, key=key):
  74. del data[key]
  75. ref = ref(default, remove)
  76. self.data[key] = ref
  77. return default
  78. else:
  79. return ref()
  80. def update(self, dict):
  81. d = self.data
  82. L = []
  83. for key, o in dict.items():
  84. def remove(o, data=d, key=key):
  85. del data[key]
  86. L.append((key, ref(o, remove)))
  87. for key, r in L:
  88. d[key] = r
  89. def values(self):
  90. L = []
  91. for ref in self.data.values():
  92. o = ref()
  93. if o is not None:
  94. L.append(o)
  95. return L
  96. class WeakKeyDictionary(UserDict.UserDict):
  97. def __init__(self, dict=None):
  98. self.data = {}
  99. if dict is not None: self.update(dict)
  100. def remove(k, data=self.data):
  101. del data[k]
  102. self._remove = remove
  103. def __getitem__(self, key):
  104. return self.data[ref(key)]
  105. def __repr__(self):
  106. return "<WeakKeyDictionary at %s>" % id(self)
  107. def __setitem__(self, key, value):
  108. self.data[ref(key, self._remove)] = value
  109. def copy(self):
  110. new = WeakKeyDictionary()
  111. for key, value in self.data.items():
  112. o = key()
  113. if o is not None:
  114. new[o] = value
  115. return new
  116. def get(self, key, default=None):
  117. return self.data.get(ref(key),default)
  118. def has_key(self, key):
  119. return self.data.has_key(ref(key))
  120. def items(self):
  121. L = []
  122. for key, value in self.data.items():
  123. o = key()
  124. if o is not None:
  125. L.append((o, value))
  126. return L
  127. def keys(self):
  128. L = []
  129. for ref in self.data.keys():
  130. o = ref()
  131. if o is not None:
  132. L.append(o)
  133. return L
  134. def popitem(self):
  135. while 1:
  136. key, value = self.data.popitem()
  137. o = key()
  138. if o is not None:
  139. return o, value
  140. def setdefault(self, key, default):
  141. return self.data.setdefault(ref(key, self._remove),default)
  142. def update(self, dict):
  143. d = self.data
  144. L = []
  145. for key, value in dict.items():
  146. L.append((ref(key, self._remove), value))
  147. for key, r in L:
  148. d[key] = r
  149. # no longer needed
  150. del UserDict