~ubuntu-branches/ubuntu/natty/python-django/natty-security

« back to all changes in this revision

Viewing changes to django/utils/datastructures.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.1.10 upstream) (4.4.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100521075255-i1zpeyc0k8512pd7
Tags: 1.2-1
New upstream stable release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from types import GeneratorType
 
2
 
 
3
from django.utils.copycompat import deepcopy
 
4
 
 
5
 
1
6
class MergeDict(object):
2
7
    """
3
8
    A simple class for creating new "virtual" dictionaries that actually look
32
37
                return dict_.getlist(key)
33
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
58
    def items(self):
36
 
        item_list = []
37
 
        for dict_ in self.dicts:
38
 
            item_list.extend(dict_.items())
39
 
        return item_list
 
59
        return list(self.iteritems())
 
60
 
 
61
    def keys(self):
 
62
        return list(self.iterkeys())
 
63
 
 
64
    def values(self):
 
65
        return list(self.itervalues())
40
66
 
41
67
    def has_key(self, key):
42
68
        for dict_ in self.dicts:
45
71
        return False
46
72
 
47
73
    __contains__ = has_key
 
74
    __iter__ = iterkeys
48
75
 
49
76
    def copy(self):
50
77
        """Returns a copy of this object."""
62
89
    def __init__(self, data=None):
63
90
        if data is None:
64
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
97
        super(SortedDict, self).__init__(data)
66
98
        if isinstance(data, dict):
67
99
            self.keyOrder = data.keys()
72
104
                    self.keyOrder.append(key)
73
105
 
74
106
    def __deepcopy__(self, memo):
75
 
        from copy import deepcopy
76
107
        return self.__class__([(key, deepcopy(value, memo))
77
108
                               for key, value in self.iteritems()])
78
109
 
79
110
    def __setitem__(self, key, value):
 
111
        if key not in self:
 
112
            self.keyOrder.append(key)
80
113
        super(SortedDict, self).__setitem__(key, value)
81
 
        if key not in self.keyOrder:
82
 
            self.keyOrder.append(key)
83
114
 
84
115
    def __delitem__(self, key):
85
116
        super(SortedDict, self).__delitem__(key)
86
117
        self.keyOrder.remove(key)
87
118
 
88
119
    def __iter__(self):
89
 
        for k in self.keyOrder:
90
 
            yield k
 
120
        return iter(self.keyOrder)
91
121
 
92
122
    def pop(self, k, *args):
93
123
        result = super(SortedDict, self).pop(k, *args)
108
138
 
109
139
    def iteritems(self):
110
140
        for key in self.keyOrder:
111
 
            yield key, super(SortedDict, self).__getitem__(key)
 
141
            yield key, self[key]
112
142
 
113
143
    def keys(self):
114
144
        return self.keyOrder[:]
117
147
        return iter(self.keyOrder)
118
148
 
119
149
    def values(self):
120
 
        return map(super(SortedDict, self).__getitem__, self.keyOrder)
 
150
        return map(self.__getitem__, self.keyOrder)
121
151
 
122
152
    def itervalues(self):
123
153
        for key in self.keyOrder:
124
 
            yield super(SortedDict, self).__getitem__(key)
 
154
            yield self[key]
125
155
 
126
156
    def update(self, dict_):
127
 
        for k, v in dict_.items():
128
 
            self.__setitem__(k, v)
 
157
        for k, v in dict_.iteritems():
 
158
            self[k] = v
129
159
 
130
160
    def setdefault(self, key, default):
131
 
        if key not in self.keyOrder:
 
161
        if key not in self:
132
162
            self.keyOrder.append(key)
133
163
        return super(SortedDict, self).setdefault(key, default)
134
164
 
200
230
        try:
201
231
            list_ = super(MultiValueDict, self).__getitem__(key)
202
232
        except KeyError:
203
 
            raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self)
 
233
            raise MultiValueDictKeyError("Key %r not found in %r" % (key, self))
204
234
        try:
205
235
            return list_[-1]
206
236
        except IndexError:
213
243
        return self.__class__(super(MultiValueDict, self).items())
214
244
 
215
245
    def __deepcopy__(self, memo=None):
216
 
        import copy
 
246
        import django.utils.copycompat as copy
217
247
        if memo is None:
218
248
            memo = {}
219
249
        result = self.__class__()
222
252
            dict.__setitem__(result, copy.deepcopy(key, memo),
223
253
                             copy.deepcopy(value, memo))
224
254
        return result
225
 
    
 
255
 
226
256
    def __getstate__(self):
227
257
        obj_dict = self.__dict__.copy()
228
258
        obj_dict['_data'] = dict([(k, self.getlist(k)) for k in self])
229
259
        return obj_dict
230
 
    
 
260
 
231
261
    def __setstate__(self, obj_dict):
232
262
        data = obj_dict.pop('_data', {})
233
263
        for k, v in data.items():
234
264
            self.setlist(k, v)
235
265
        self.__dict__.update(obj_dict)
236
 
        
 
266
 
237
267
    def get(self, key, default=None):
238
268
        """
239
269
        Returns the last data value for the passed key. If key doesn't exist
301
331
    def values(self):
302
332
        """Returns a list of the last value on every key list."""
303
333
        return [self[key] for key in self.keys()]
304
 
        
 
334
 
305
335
    def itervalues(self):
306
336
        """Yield the last value on every key list."""
307
337
        for key in self.iterkeys():
308
338
            yield self[key]
309
 
    
 
339
 
310
340
    def copy(self):
311
341
        """Returns a copy of this object."""
312
342
        return self.__deepcopy__()
317
347
        Also accepts keyword args.
318
348
        """
319
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
351
        if args:
322
352
            other_dict = args[0]
323
353
            if isinstance(other_dict, MultiValueDict):
328
358
                    for key, value in other_dict.items():
329
359
                        self.setlistdefault(key, []).append(value)
330
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
362
        for key, value in kwargs.iteritems():
333
363
            self.setlistdefault(key, []).append(value)
334
364
 
392
422
        if isinstance(self.warning, Exception):
393
423
            raise self.warning
394
424
        else:
395
 
            raise AttributeError, self.warning
 
425
            raise AttributeError(self.warning)
396
426
 
397
427
    # All list mutation functions complain.
398
428
    __delitem__  = complain