blob: bd64f84d4252866eaf61840617fb748363798bc2 [file] [log] [blame]
Guido van Rossum4acc25b2000-02-02 15:10:15 +00001"""A more or less complete user-defined wrapper around dictionary objects."""
Guido van Rossumae3b3a31993-11-30 13:43:54 +00002
Benjamin Peterson17527be2010-01-27 02:15:28 +00003class UserDict(object):
Raymond Hettinger54405452002-11-22 00:07:40 +00004 def __init__(self, dict=None, **kwargs):
Raymond Hettingere4827eb2002-11-27 08:29:11 +00005 self.data = {}
Raymond Hettinger54405452002-11-22 00:07:40 +00006 if dict is not None:
Raymond Hettingere4827eb2002-11-27 08:29:11 +00007 self.update(dict)
8 if len(kwargs):
9 self.update(kwargs)
Guido van Rossumb94cd961997-06-03 14:10:01 +000010 def __repr__(self): return repr(self.data)
11 def __cmp__(self, dict):
Guido van Rossum1697b9c1999-03-26 15:31:12 +000012 if isinstance(dict, UserDict):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000013 return cmp(self.data, dict.data)
Guido van Rossum1697b9c1999-03-26 15:31:12 +000014 else:
15 return cmp(self.data, dict)
Benjamin Peterson11fab6c2010-01-28 02:18:25 +000016 __hash__ = None # Avoid Py3k warning
Guido van Rossumb94cd961997-06-03 14:10:01 +000017 def __len__(self): return len(self.data)
Guido van Rossum1968ad32006-02-25 22:38:04 +000018 def __getitem__(self, key):
19 if key in self.data:
20 return self.data[key]
21 if hasattr(self.__class__, "__missing__"):
22 return self.__class__.__missing__(self, key)
23 raise KeyError(key)
Guido van Rossumb94cd961997-06-03 14:10:01 +000024 def __setitem__(self, key, item): self.data[key] = item
25 def __delitem__(self, key): del self.data[key]
Guido van Rossum1697b9c1999-03-26 15:31:12 +000026 def clear(self): self.data.clear()
Guido van Rossumb94cd961997-06-03 14:10:01 +000027 def copy(self):
Guido van Rossum1697b9c1999-03-26 15:31:12 +000028 if self.__class__ is UserDict:
Raymond Hettinger90145602003-12-21 22:19:08 +000029 return UserDict(self.data.copy())
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000030 import copy
Fred Drake3ce5af72001-11-05 17:40:48 +000031 data = self.data
32 try:
33 self.data = {}
34 c = copy.copy(self)
35 finally:
36 self.data = data
37 c.update(self)
38 return c
Guido van Rossumb94cd961997-06-03 14:10:01 +000039 def keys(self): return self.data.keys()
40 def items(self): return self.data.items()
Fred Drakebedebbd2001-05-03 04:54:41 +000041 def iteritems(self): return self.data.iteritems()
42 def iterkeys(self): return self.data.iterkeys()
43 def itervalues(self): return self.data.itervalues()
Guido van Rossumb94cd961997-06-03 14:10:01 +000044 def values(self): return self.data.values()
Raymond Hettinger31ce5cb2008-02-21 19:24:53 +000045 def has_key(self, key): return key in self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +000046 def update(self, dict=None, **kwargs):
47 if dict is None:
48 pass
49 elif isinstance(dict, UserDict):
Guido van Rossum1697b9c1999-03-26 15:31:12 +000050 self.data.update(dict.data)
Raymond Hettinger31017ae2004-03-04 08:25:44 +000051 elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
Guido van Rossum1697b9c1999-03-26 15:31:12 +000052 self.data.update(dict)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000053 else:
Guido van Rossum1697b9c1999-03-26 15:31:12 +000054 for k, v in dict.items():
Martin v. Löwisf3b30742001-06-18 01:09:41 +000055 self[k] = v
Raymond Hettinger31017ae2004-03-04 08:25:44 +000056 if len(kwargs):
57 self.data.update(kwargs)
Barry Warsawfc3e61c1997-10-06 17:50:04 +000058 def get(self, key, failobj=None):
Guido van Rossum8bc09652008-02-21 18:18:37 +000059 if key not in self:
Martin v. Löwisf3b30742001-06-18 01:09:41 +000060 return failobj
61 return self[key]
Guido van Rossum164452c2000-08-08 16:12:54 +000062 def setdefault(self, key, failobj=None):
Raymond Hettinger31ce5cb2008-02-21 19:24:53 +000063 if key not in self:
Martin v. Löwisf3b30742001-06-18 01:09:41 +000064 self[key] = failobj
65 return self[key]
Raymond Hettingera3e1e4c2003-03-06 23:54:28 +000066 def pop(self, key, *args):
67 return self.data.pop(key, *args)
Guido van Rossum1072c382000-12-12 22:06:00 +000068 def popitem(self):
69 return self.data.popitem()
Tim Petersa3f98d62001-04-21 09:13:15 +000070 def __contains__(self, key):
71 return key in self.data
Guido van Rossum75b64e62005-01-16 00:16:11 +000072 @classmethod
Raymond Hettingere4827eb2002-11-27 08:29:11 +000073 def fromkeys(cls, iterable, value=None):
74 d = cls()
75 for key in iterable:
76 d[key] = value
77 return d
Guido van Rossum2050b652001-08-07 17:40:42 +000078
79class IterableUserDict(UserDict):
Tim Petersa3f98d62001-04-21 09:13:15 +000080 def __iter__(self):
81 return iter(self.data)
Raymond Hettinger79947162002-11-15 06:46:14 +000082
Georg Brandl3bed4ae2008-06-07 16:16:12 +000083import _abcoll
84_abcoll.MutableMapping.register(IterableUserDict)
85
86
Raymond Hettinger79947162002-11-15 06:46:14 +000087class DictMixin:
Raymond Hettinger8ddc1762002-11-18 04:34:10 +000088 # Mixin defining all dictionary methods for classes that already have
89 # a minimum dictionary interface including getitem, setitem, delitem,
90 # and keys. Without knowledge of the subclass constructor, the mixin
91 # does not define __init__() or copy(). In addition to the four base
Barry Warsaw1a177042003-01-31 03:30:09 +000092 # methods, progressively more efficiency comes with defining
Raymond Hettinger8ddc1762002-11-18 04:34:10 +000093 # __contains__(), __iter__(), and iteritems().
Raymond Hettinger79947162002-11-15 06:46:14 +000094
Raymond Hettinger8ddc1762002-11-18 04:34:10 +000095 # second level definitions support higher levels
96 def __iter__(self):
97 for k in self.keys():
98 yield k
Raymond Hettinger79947162002-11-15 06:46:14 +000099 def has_key(self, key):
100 try:
Georg Brandl84fedf72010-02-06 22:59:15 +0000101 self[key]
Raymond Hettinger79947162002-11-15 06:46:14 +0000102 except KeyError:
103 return False
104 return True
Raymond Hettinger51f3f1b2003-01-22 01:39:06 +0000105 def __contains__(self, key):
106 return self.has_key(key)
Raymond Hettinger79947162002-11-15 06:46:14 +0000107
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000108 # third level takes advantage of second level definitions
Raymond Hettinger79947162002-11-15 06:46:14 +0000109 def iteritems(self):
110 for k in self:
111 yield (k, self[k])
Raymond Hettinger51f3f1b2003-01-22 01:39:06 +0000112 def iterkeys(self):
113 return self.__iter__()
Raymond Hettinger79947162002-11-15 06:46:14 +0000114
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000115 # fourth level uses definitions from lower levels
Raymond Hettinger79947162002-11-15 06:46:14 +0000116 def itervalues(self):
117 for _, v in self.iteritems():
118 yield v
119 def values(self):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000120 return [v for _, v in self.iteritems()]
Raymond Hettinger79947162002-11-15 06:46:14 +0000121 def items(self):
122 return list(self.iteritems())
123 def clear(self):
124 for key in self.keys():
125 del self[key]
Walter Dörwaldc1399092004-05-27 09:41:04 +0000126 def setdefault(self, key, default=None):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000127 try:
128 return self[key]
129 except KeyError:
Raymond Hettinger79947162002-11-15 06:46:14 +0000130 self[key] = default
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000131 return default
Raymond Hettingera3e1e4c2003-03-06 23:54:28 +0000132 def pop(self, key, *args):
133 if len(args) > 1:
134 raise TypeError, "pop expected at most 2 arguments, got "\
135 + repr(1 + len(args))
136 try:
137 value = self[key]
138 except KeyError:
139 if args:
140 return args[0]
141 raise
Raymond Hettinger79947162002-11-15 06:46:14 +0000142 del self[key]
143 return value
144 def popitem(self):
145 try:
146 k, v = self.iteritems().next()
147 except StopIteration:
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000148 raise KeyError, 'container is empty'
Raymond Hettinger79947162002-11-15 06:46:14 +0000149 del self[k]
150 return (k, v)
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000151 def update(self, other=None, **kwargs):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000152 # Make progressively weaker assumptions about "other"
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000153 if other is None:
154 pass
155 elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000156 for k, v in other.iteritems():
157 self[k] = v
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000158 elif hasattr(other, 'keys'):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000159 for k in other.keys():
160 self[k] = other[k]
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000161 else:
162 for k, v in other:
163 self[k] = v
164 if kwargs:
165 self.update(kwargs)
Raymond Hettinger79947162002-11-15 06:46:14 +0000166 def get(self, key, default=None):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000167 try:
Raymond Hettinger79947162002-11-15 06:46:14 +0000168 return self[key]
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000169 except KeyError:
170 return default
Raymond Hettinger79947162002-11-15 06:46:14 +0000171 def __repr__(self):
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000172 return repr(dict(self.iteritems()))
173 def __cmp__(self, other):
Raymond Hettingerf477c882003-12-04 20:04:09 +0000174 if other is None:
175 return 1
Raymond Hettinger8ddc1762002-11-18 04:34:10 +0000176 if isinstance(other, DictMixin):
177 other = dict(other.iteritems())
178 return cmp(dict(self.iteritems()), other)
179 def __len__(self):
180 return len(self.keys())