github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/third_party/stdlib/UserDict.py (about) 1 """A more or less complete user-defined wrapper around dictionary objects.""" 2 3 class UserDict(object): 4 def __init__(*args, **kwargs): 5 if not args: 6 raise TypeError("descriptor '__init__' of 'UserDict' object " 7 "needs an argument") 8 self = args[0] 9 args = args[1:] 10 if len(args) > 1: 11 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 12 if args: 13 dict = args[0] 14 elif 'dict' in kwargs: 15 dict = kwargs.pop('dict') 16 import warnings 17 warnings.warn("Passing 'dict' as keyword argument is " 18 "deprecated", PendingDeprecationWarning, 19 stacklevel=2) 20 else: 21 dict = None 22 self.data = {} 23 if dict is not None: 24 self.update(dict) 25 if len(kwargs): 26 self.update(kwargs) 27 def __repr__(self): return repr(self.data) 28 def __cmp__(self, dict): 29 if isinstance(dict, UserDict): 30 return cmp(self.data, dict.data) 31 else: 32 return cmp(self.data, dict) 33 __hash__ = None # Avoid Py3k warning 34 def __len__(self): return len(self.data) 35 def __getitem__(self, key): 36 if key in self.data: 37 return self.data[key] 38 if hasattr(self.__class__, "__missing__"): 39 return self.__class__.__missing__(self, key) 40 raise KeyError(key) 41 def __setitem__(self, key, item): self.data[key] = item 42 def __delitem__(self, key): del self.data[key] 43 def clear(self): self.data.clear() 44 def copy(self): 45 if self.__class__ is UserDict: 46 return UserDict(self.data.copy()) 47 import copy 48 data = self.data 49 try: 50 self.data = {} 51 c = copy.copy(self) 52 finally: 53 self.data = data 54 c.update(self) 55 return c 56 def keys(self): return self.data.keys() 57 def items(self): return self.data.items() 58 def iteritems(self): return self.data.iteritems() 59 def iterkeys(self): return self.data.iterkeys() 60 def itervalues(self): return self.data.itervalues() 61 def values(self): return self.data.values() 62 def has_key(self, key): return key in self.data 63 def update(*args, **kwargs): 64 if not args: 65 raise TypeError("descriptor 'update' of 'UserDict' object " 66 "needs an argument") 67 self = args[0] 68 args = args[1:] 69 if len(args) > 1: 70 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 71 if args: 72 dict = args[0] 73 elif 'dict' in kwargs: 74 dict = kwargs.pop('dict') 75 import warnings 76 warnings.warn("Passing 'dict' as keyword argument is deprecated", 77 PendingDeprecationWarning, stacklevel=2) 78 else: 79 dict = None 80 if dict is None: 81 pass 82 elif isinstance(dict, UserDict): 83 self.data.update(dict.data) 84 elif isinstance(dict, type({})) or not hasattr(dict, 'items'): 85 self.data.update(dict) 86 else: 87 for k, v in dict.items(): 88 self[k] = v 89 if len(kwargs): 90 self.data.update(kwargs) 91 def get(self, key, failobj=None): 92 if key not in self: 93 return failobj 94 return self[key] 95 def setdefault(self, key, failobj=None): 96 if key not in self: 97 self[key] = failobj 98 return self[key] 99 def pop(self, key, *args): 100 return self.data.pop(key, *args) 101 def popitem(self): 102 return self.data.popitem() 103 def __contains__(self, key): 104 return key in self.data 105 def fromkeys(cls, iterable, value=None): 106 d = cls() 107 for key in iterable: 108 d[key] = value 109 return d 110 # TODO: Make this a decorator once they're implemented. 111 fromkeys = classmethod(fromkeys) 112 113 class IterableUserDict(UserDict): 114 def __iter__(self): 115 return iter(self.data) 116 117 import _abcoll 118 _abcoll.MutableMapping.register(IterableUserDict) 119 120 121 class DictMixin(object): 122 # Mixin defining all dictionary methods for classes that already have 123 # a minimum dictionary interface including getitem, setitem, delitem, 124 # and keys. Without knowledge of the subclass constructor, the mixin 125 # does not define __init__() or copy(). In addition to the four base 126 # methods, progressively more efficiency comes with defining 127 # __contains__(), __iter__(), and iteritems(). 128 129 # second level definitions support higher levels 130 def __iter__(self): 131 for k in self.keys(): 132 yield k 133 def has_key(self, key): 134 try: 135 self[key] 136 except KeyError: 137 return False 138 return True 139 def __contains__(self, key): 140 return self.has_key(key) 141 142 # third level takes advantage of second level definitions 143 def iteritems(self): 144 for k in self: 145 yield (k, self[k]) 146 def iterkeys(self): 147 return self.__iter__() 148 149 # fourth level uses definitions from lower levels 150 def itervalues(self): 151 for _, v in self.iteritems(): 152 yield v 153 def values(self): 154 return [v for _, v in self.iteritems()] 155 def items(self): 156 return list(self.iteritems()) 157 def clear(self): 158 for key in self.keys(): 159 del self[key] 160 def setdefault(self, key, default=None): 161 try: 162 return self[key] 163 except KeyError: 164 self[key] = default 165 return default 166 def pop(self, key, *args): 167 if len(args) > 1: 168 raise TypeError, "pop expected at most 2 arguments, got "\ 169 + repr(1 + len(args)) 170 try: 171 value = self[key] 172 except KeyError: 173 if args: 174 return args[0] 175 raise 176 del self[key] 177 return value 178 def popitem(self): 179 try: 180 k, v = self.iteritems().next() 181 except StopIteration: 182 raise KeyError, 'container is empty' 183 del self[k] 184 return (k, v) 185 def update(self, other=None, **kwargs): 186 # Make progressively weaker assumptions about "other" 187 if other is None: 188 pass 189 elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups 190 for k, v in other.iteritems(): 191 self[k] = v 192 elif hasattr(other, 'keys'): 193 for k in other.keys(): 194 self[k] = other[k] 195 else: 196 for k, v in other: 197 self[k] = v 198 if kwargs: 199 self.update(kwargs) 200 def get(self, key, default=None): 201 try: 202 return self[key] 203 except KeyError: 204 return default 205 def __repr__(self): 206 return repr(dict(self.iteritems())) 207 def __cmp__(self, other): 208 if other is None: 209 return 1 210 if isinstance(other, DictMixin): 211 other = dict(other.iteritems()) 212 return cmp(dict(self.iteritems()), other) 213 def __len__(self): 214 return len(self.keys())