30 for dict_ in self.dicts: |
35 for dict_ in self.dicts: |
31 if key in dict_.keys(): |
36 if key in dict_.keys(): |
32 return dict_.getlist(key) |
37 return dict_.getlist(key) |
33 return [] |
38 return [] |
34 |
39 |
|
40 def iteritems(self): |
|
41 seen = set() |
|
42 for dict_ in self.dicts: |
|
43 for item in dict_.iteritems(): |
|
44 k, v = item |
|
45 if k in seen: |
|
46 continue |
|
47 seen.add(k) |
|
48 yield item |
|
49 |
|
50 def iterkeys(self): |
|
51 for k, v in self.iteritems(): |
|
52 yield k |
|
53 |
|
54 def itervalues(self): |
|
55 for k, v in self.iteritems(): |
|
56 yield v |
|
57 |
35 def items(self): |
58 def items(self): |
36 item_list = [] |
59 return list(self.iteritems()) |
37 for dict_ in self.dicts: |
60 |
38 item_list.extend(dict_.items()) |
61 def keys(self): |
39 return item_list |
62 return list(self.iterkeys()) |
|
63 |
|
64 def values(self): |
|
65 return list(self.itervalues()) |
40 |
66 |
41 def has_key(self, key): |
67 def has_key(self, key): |
42 for dict_ in self.dicts: |
68 for dict_ in self.dicts: |
43 if key in dict_: |
69 if key in dict_: |
44 return True |
70 return True |
45 return False |
71 return False |
46 |
72 |
47 __contains__ = has_key |
73 __contains__ = has_key |
|
74 __iter__ = iterkeys |
48 |
75 |
49 def copy(self): |
76 def copy(self): |
50 """Returns a copy of this object.""" |
77 """Returns a copy of this object.""" |
51 return self.__copy__() |
78 return self.__copy__() |
52 |
79 |
60 return instance |
87 return instance |
61 |
88 |
62 def __init__(self, data=None): |
89 def __init__(self, data=None): |
63 if data is None: |
90 if data is None: |
64 data = {} |
91 data = {} |
|
92 elif isinstance(data, GeneratorType): |
|
93 # Unfortunately we need to be able to read a generator twice. Once |
|
94 # to get the data into self with our super().__init__ call and a |
|
95 # second time to setup keyOrder correctly |
|
96 data = list(data) |
65 super(SortedDict, self).__init__(data) |
97 super(SortedDict, self).__init__(data) |
66 if isinstance(data, dict): |
98 if isinstance(data, dict): |
67 self.keyOrder = data.keys() |
99 self.keyOrder = data.keys() |
68 else: |
100 else: |
69 self.keyOrder = [] |
101 self.keyOrder = [] |
70 for key, value in data: |
102 for key, value in data: |
71 if key not in self.keyOrder: |
103 if key not in self.keyOrder: |
72 self.keyOrder.append(key) |
104 self.keyOrder.append(key) |
73 |
105 |
74 def __deepcopy__(self, memo): |
106 def __deepcopy__(self, memo): |
75 from copy import deepcopy |
|
76 return self.__class__([(key, deepcopy(value, memo)) |
107 return self.__class__([(key, deepcopy(value, memo)) |
77 for key, value in self.iteritems()]) |
108 for key, value in self.iteritems()]) |
78 |
109 |
79 def __setitem__(self, key, value): |
110 def __setitem__(self, key, value): |
|
111 if key not in self: |
|
112 self.keyOrder.append(key) |
80 super(SortedDict, self).__setitem__(key, value) |
113 super(SortedDict, self).__setitem__(key, value) |
81 if key not in self.keyOrder: |
|
82 self.keyOrder.append(key) |
|
83 |
114 |
84 def __delitem__(self, key): |
115 def __delitem__(self, key): |
85 super(SortedDict, self).__delitem__(key) |
116 super(SortedDict, self).__delitem__(key) |
86 self.keyOrder.remove(key) |
117 self.keyOrder.remove(key) |
87 |
118 |
88 def __iter__(self): |
119 def __iter__(self): |
89 for k in self.keyOrder: |
120 return iter(self.keyOrder) |
90 yield k |
|
91 |
121 |
92 def pop(self, k, *args): |
122 def pop(self, k, *args): |
93 result = super(SortedDict, self).pop(k, *args) |
123 result = super(SortedDict, self).pop(k, *args) |
94 try: |
124 try: |
95 self.keyOrder.remove(k) |
125 self.keyOrder.remove(k) |
106 def items(self): |
136 def items(self): |
107 return zip(self.keyOrder, self.values()) |
137 return zip(self.keyOrder, self.values()) |
108 |
138 |
109 def iteritems(self): |
139 def iteritems(self): |
110 for key in self.keyOrder: |
140 for key in self.keyOrder: |
111 yield key, super(SortedDict, self).__getitem__(key) |
141 yield key, self[key] |
112 |
142 |
113 def keys(self): |
143 def keys(self): |
114 return self.keyOrder[:] |
144 return self.keyOrder[:] |
115 |
145 |
116 def iterkeys(self): |
146 def iterkeys(self): |
117 return iter(self.keyOrder) |
147 return iter(self.keyOrder) |
118 |
148 |
119 def values(self): |
149 def values(self): |
120 return map(super(SortedDict, self).__getitem__, self.keyOrder) |
150 return map(self.__getitem__, self.keyOrder) |
121 |
151 |
122 def itervalues(self): |
152 def itervalues(self): |
123 for key in self.keyOrder: |
153 for key in self.keyOrder: |
124 yield super(SortedDict, self).__getitem__(key) |
154 yield self[key] |
125 |
155 |
126 def update(self, dict_): |
156 def update(self, dict_): |
127 for k, v in dict_.items(): |
157 for k, v in dict_.iteritems(): |
128 self.__setitem__(k, v) |
158 self[k] = v |
129 |
159 |
130 def setdefault(self, key, default): |
160 def setdefault(self, key, default): |
131 if key not in self.keyOrder: |
161 if key not in self: |
132 self.keyOrder.append(key) |
162 self.keyOrder.append(key) |
133 return super(SortedDict, self).setdefault(key, default) |
163 return super(SortedDict, self).setdefault(key, default) |
134 |
164 |
135 def value_for_index(self, index): |
165 def value_for_index(self, index): |
136 """Returns the value of the item at the given zero-based index.""" |
166 """Returns the value of the item at the given zero-based index.""" |
211 |
241 |
212 def __copy__(self): |
242 def __copy__(self): |
213 return self.__class__(super(MultiValueDict, self).items()) |
243 return self.__class__(super(MultiValueDict, self).items()) |
214 |
244 |
215 def __deepcopy__(self, memo=None): |
245 def __deepcopy__(self, memo=None): |
216 import copy |
246 import django.utils.copycompat as copy |
217 if memo is None: |
247 if memo is None: |
218 memo = {} |
248 memo = {} |
219 result = self.__class__() |
249 result = self.__class__() |
220 memo[id(self)] = result |
250 memo[id(self)] = result |
221 for key, value in dict.items(self): |
251 for key, value in dict.items(self): |
222 dict.__setitem__(result, copy.deepcopy(key, memo), |
252 dict.__setitem__(result, copy.deepcopy(key, memo), |
223 copy.deepcopy(value, memo)) |
253 copy.deepcopy(value, memo)) |
224 return result |
254 return result |
225 |
255 |
226 def __getstate__(self): |
256 def __getstate__(self): |
227 obj_dict = self.__dict__.copy() |
257 obj_dict = self.__dict__.copy() |
228 obj_dict['_data'] = dict([(k, self.getlist(k)) for k in self]) |
258 obj_dict['_data'] = dict([(k, self.getlist(k)) for k in self]) |
229 return obj_dict |
259 return obj_dict |
230 |
260 |
231 def __setstate__(self, obj_dict): |
261 def __setstate__(self, obj_dict): |
232 data = obj_dict.pop('_data', {}) |
262 data = obj_dict.pop('_data', {}) |
233 for k, v in data.items(): |
263 for k, v in data.items(): |
234 self.setlist(k, v) |
264 self.setlist(k, v) |
235 self.__dict__.update(obj_dict) |
265 self.__dict__.update(obj_dict) |
236 |
266 |
237 def get(self, key, default=None): |
267 def get(self, key, default=None): |
238 """ |
268 """ |
239 Returns the last data value for the passed key. If key doesn't exist |
269 Returns the last data value for the passed key. If key doesn't exist |
240 or value is an empty list, then default is returned. |
270 or value is an empty list, then default is returned. |
241 """ |
271 """ |
299 return super(MultiValueDict, self).iteritems() |
329 return super(MultiValueDict, self).iteritems() |
300 |
330 |
301 def values(self): |
331 def values(self): |
302 """Returns a list of the last value on every key list.""" |
332 """Returns a list of the last value on every key list.""" |
303 return [self[key] for key in self.keys()] |
333 return [self[key] for key in self.keys()] |
304 |
334 |
305 def itervalues(self): |
335 def itervalues(self): |
306 """Yield the last value on every key list.""" |
336 """Yield the last value on every key list.""" |
307 for key in self.iterkeys(): |
337 for key in self.iterkeys(): |
308 yield self[key] |
338 yield self[key] |
309 |
339 |
310 def copy(self): |
340 def copy(self): |
311 """Returns a copy of this object.""" |
341 """Returns a copy of this object.""" |
312 return self.__deepcopy__() |
342 return self.__deepcopy__() |
313 |
343 |
314 def update(self, *args, **kwargs): |
344 def update(self, *args, **kwargs): |
315 """ |
345 """ |
316 update() extends rather than replaces existing key lists. |
346 update() extends rather than replaces existing key lists. |
317 Also accepts keyword args. |
347 Also accepts keyword args. |
318 """ |
348 """ |
319 if len(args) > 1: |
349 if len(args) > 1: |
320 raise TypeError, "update expected at most 1 arguments, got %d" % len(args) |
350 raise TypeError("update expected at most 1 arguments, got %d" % len(args)) |
321 if args: |
351 if args: |
322 other_dict = args[0] |
352 other_dict = args[0] |
323 if isinstance(other_dict, MultiValueDict): |
353 if isinstance(other_dict, MultiValueDict): |
324 for key, value_list in other_dict.lists(): |
354 for key, value_list in other_dict.lists(): |
325 self.setlistdefault(key, []).extend(value_list) |
355 self.setlistdefault(key, []).extend(value_list) |
326 else: |
356 else: |
327 try: |
357 try: |
328 for key, value in other_dict.items(): |
358 for key, value in other_dict.items(): |
329 self.setlistdefault(key, []).append(value) |
359 self.setlistdefault(key, []).append(value) |
330 except TypeError: |
360 except TypeError: |
331 raise ValueError, "MultiValueDict.update() takes either a MultiValueDict or dictionary" |
361 raise ValueError("MultiValueDict.update() takes either a MultiValueDict or dictionary") |
332 for key, value in kwargs.iteritems(): |
362 for key, value in kwargs.iteritems(): |
333 self.setlistdefault(key, []).append(value) |
363 self.setlistdefault(key, []).append(value) |
334 |
364 |
335 class DotExpandedDict(dict): |
365 class DotExpandedDict(dict): |
336 """ |
366 """ |
390 |
420 |
391 def complain(self, *wargs, **kwargs): |
421 def complain(self, *wargs, **kwargs): |
392 if isinstance(self.warning, Exception): |
422 if isinstance(self.warning, Exception): |
393 raise self.warning |
423 raise self.warning |
394 else: |
424 else: |
395 raise AttributeError, self.warning |
425 raise AttributeError(self.warning) |
396 |
426 |
397 # All list mutation functions complain. |
427 # All list mutation functions complain. |
398 __delitem__ = complain |
428 __delitem__ = complain |
399 __delslice__ = complain |
429 __delslice__ = complain |
400 __iadd__ = complain |
430 __iadd__ = complain |