source file: /System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/UserDict.py
file stats: 142 lines, 3 executed: 2.1% covered
1. """A more or less complete user-defined wrapper around dictionary objects.""" 2. 3. class UserDict: 4. def __init__(self, dict=None, **kwargs): 5. self.data = {} 6. if dict is not None: 7. if not hasattr(dict,'keys'): 8. dict = type({})(dict) # make mapping from a sequence 9. self.update(dict) 10. if len(kwargs): 11. self.update(kwargs) 12. def __repr__(self): return repr(self.data) 13. def __cmp__(self, dict): 14. if isinstance(dict, UserDict): 15. return cmp(self.data, dict.data) 16. else: 17. return cmp(self.data, dict) 18. def __len__(self): return len(self.data) 19. def __getitem__(self, key): return self.data[key] 20. def __setitem__(self, key, item): self.data[key] = item 21. def __delitem__(self, key): del self.data[key] 22. def clear(self): self.data.clear() 23. def copy(self): 24. if self.__class__ is UserDict: 25. return UserDict(self.data) 26. import copy 27. data = self.data 28. try: 29. self.data = {} 30. c = copy.copy(self) 31. finally: 32. self.data = data 33. c.update(self) 34. return c 35. def keys(self): return self.data.keys() 36. def items(self): return self.data.items() 37. def iteritems(self): return self.data.iteritems() 38. def iterkeys(self): return self.data.iterkeys() 39. def itervalues(self): return self.data.itervalues() 40. def values(self): return self.data.values() 41. def has_key(self, key): return self.data.has_key(key) 42. def update(self, dict): 43. if isinstance(dict, UserDict): 44. self.data.update(dict.data) 45. elif isinstance(dict, type(self.data)): 46. self.data.update(dict) 47. else: 48. for k, v in dict.items(): 49. self[k] = v 50. def get(self, key, failobj=None): 51. if not self.has_key(key): 52. return failobj 53. return self[key] 54. def setdefault(self, key, failobj=None): 55. if not self.has_key(key): 56. self[key] = failobj 57. return self[key] 58. def pop(self, key, *args): 59. return self.data.pop(key, *args) 60. def popitem(self): 61. return self.data.popitem() 62. def __contains__(self, key): 63. return key in self.data 64. def fromkeys(cls, iterable, value=None): 65. d = cls() 66. for key in iterable: 67. d[key] = value 68. return d 69. fromkeys = classmethod(fromkeys) 70. 71. class IterableUserDict(UserDict): 72. def __iter__(self): 73. return iter(self.data) 74. 75. class DictMixin: 76. # Mixin defining all dictionary methods for classes that already have 77. # a minimum dictionary interface including getitem, setitem, delitem, 78. # and keys. Without knowledge of the subclass constructor, the mixin 79. # does not define __init__() or copy(). In addition to the four base 80. # methods, progressively more efficiency comes with defining 81. # __contains__(), __iter__(), and iteritems(). 82. 83. # second level definitions support higher levels 84. def __iter__(self): 85. for k in self.keys(): 86. yield k 87. def has_key(self, key): 88. try: 89. value = self[key] 90. except KeyError: 91. return False 92. return True 93. def __contains__(self, key): 94. return self.has_key(key) 95. 96. # third level takes advantage of second level definitions 97. def iteritems(self): 98. for k in self: 99. yield (k, self[k]) 100. def iterkeys(self): 101. return self.__iter__() 102. 103. # fourth level uses definitions from lower levels 104. def itervalues(self): 105. for _, v in self.iteritems(): 106. yield v 107. def values(self): 108. return [v for _, v in self.iteritems()] 109. def items(self): 110. return list(self.iteritems()) 111. def clear(self): 112. for key in self.keys(): 113. del self[key] 114. def setdefault(self, key, default): 115. try: 116. return self[key] 117. except KeyError: 118. self[key] = default 119. return default 120. def pop(self, key, *args): 121. if len(args) > 1: 122. raise TypeError, "pop expected at most 2 arguments, got "\ 123. + repr(1 + len(args)) 124. try: 125. value = self[key] 126. except KeyError: 127. if args: 128. return args[0] 129. raise 130. del self[key] 131. return value 132. def popitem(self): 133. try: 134. k, v = self.iteritems().next() 135. except StopIteration: 136. raise KeyError, 'container is empty' 137. del self[k] 138. return (k, v) 139. def update(self, other): 140. # Make progressively weaker assumptions about "other" 141. if hasattr(other, 'iteritems'): # iteritems saves memory and lookups 142. for k, v in other.iteritems(): 143. self[k] = v 144. elif hasattr(other, '__iter__'): # iter saves memory 145. for k in other: 146. self[k] = other[k] 147. else: 148. for k in other.keys(): 149. self[k] = other[k] 150. def get(self, key, default=None): 151. try: 152. return self[key] 153. except KeyError: 154. return default 155. def __repr__(self): 156. return repr(dict(self.iteritems())) 157. def __cmp__(self, other): 158. if other is None: 159. return 1 160. if isinstance(other, DictMixin): 161. other = dict(other.iteritems()) 162. return cmp(dict(self.iteritems()), other) 163. def __len__(self): 164. return len(self.keys())