app/django/utils/datastructures.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
    52 
    52 
    53 class SortedDict(dict):
    53 class SortedDict(dict):
    54     """
    54     """
    55     A dictionary that keeps its keys in the order in which they're inserted.
    55     A dictionary that keeps its keys in the order in which they're inserted.
    56     """
    56     """
       
    57     def __new__(cls, *args, **kwargs):
       
    58         instance = super(SortedDict, cls).__new__(cls, *args, **kwargs)
       
    59         instance.keyOrder = []
       
    60         return instance
       
    61 
    57     def __init__(self, data=None):
    62     def __init__(self, data=None):
    58         if data is None:
    63         if data is None:
    59             data = {}
    64             data = {}
    60         super(SortedDict, self).__init__(data)
    65         super(SortedDict, self).__init__(data)
    61         if isinstance(data, dict):
    66         if isinstance(data, dict):
   263         """
   268         """
   264         Returns a list of (key, value) pairs, where value is the last item in
   269         Returns a list of (key, value) pairs, where value is the last item in
   265         the list associated with the key.
   270         the list associated with the key.
   266         """
   271         """
   267         return [(key, self[key]) for key in self.keys()]
   272         return [(key, self[key]) for key in self.keys()]
       
   273 
       
   274     def iteritems(self):
       
   275         """
       
   276         Yields (key, value) pairs, where value is the last item in the list
       
   277         associated with the key.
       
   278         """
       
   279         for key in self.keys():
       
   280             yield (key, self[key])
   268 
   281 
   269     def lists(self):
   282     def lists(self):
   270         """Returns a list of (key, list) pairs."""
   283         """Returns a list of (key, list) pairs."""
   271         return super(MultiValueDict, self).items()
   284         return super(MultiValueDict, self).items()
   272 
   285 
   330             try:
   343             try:
   331                 current[bits[-1]] = v
   344                 current[bits[-1]] = v
   332             except TypeError: # Special-case if current isn't a dict.
   345             except TypeError: # Special-case if current isn't a dict.
   333                 current = {bits[-1]: v}
   346                 current = {bits[-1]: v}
   334 
   347 
   335 class FileDict(dict):
   348 class ImmutableList(tuple):
   336     """
   349     """
   337     A dictionary used to hold uploaded file contents. The only special feature
   350     A tuple-like object that raises useful errors when it is asked to mutate.
   338     here is that repr() of this object won't dump the entire contents of the
   351 
   339     file to the output. A handy safeguard for a large file upload.
   352     Example::
   340     """
   353 
   341     def __repr__(self):
   354         >>> a = ImmutableList(range(5), warning="You cannot mutate this.")
   342         if 'content' in self:
   355         >>> a[3] = '4'
   343             d = dict(self, content='<omitted>')
   356         Traceback (most recent call last):
   344             return dict.__repr__(d)
   357             ...
   345         return dict.__repr__(self)
   358         AttributeError: You cannot mutate this.
       
   359     """
       
   360 
       
   361     def __new__(cls, *args, **kwargs):
       
   362         if 'warning' in kwargs:
       
   363             warning = kwargs['warning']
       
   364             del kwargs['warning']
       
   365         else:
       
   366             warning = 'ImmutableList object is immutable.'
       
   367         self = tuple.__new__(cls, *args, **kwargs)
       
   368         self.warning = warning
       
   369         return self
       
   370 
       
   371     def complain(self, *wargs, **kwargs):
       
   372         if isinstance(self.warning, Exception):
       
   373             raise self.warning
       
   374         else:
       
   375             raise AttributeError, self.warning
       
   376 
       
   377     # All list mutation functions complain.
       
   378     __delitem__  = complain
       
   379     __delslice__ = complain
       
   380     __iadd__     = complain
       
   381     __imul__     = complain
       
   382     __setitem__  = complain
       
   383     __setslice__ = complain
       
   384     append       = complain
       
   385     extend       = complain
       
   386     insert       = complain
       
   387     pop          = complain
       
   388     remove       = complain
       
   389     sort         = complain
       
   390     reverse      = complain
       
   391 
       
   392 class DictWrapper(dict):
       
   393     """
       
   394     Wraps accesses to a dictionary so that certain values (those starting with
       
   395     the specified prefix) are passed through a function before being returned.
       
   396     The prefix is removed before looking up the real value.
       
   397 
       
   398     Used by the SQL construction code to ensure that values are correctly
       
   399     quoted before being used.
       
   400     """
       
   401     def __init__(self, data, func, prefix):
       
   402         super(DictWrapper, self).__init__(data)
       
   403         self.func = func
       
   404         self.prefix = prefix
       
   405 
       
   406     def __getitem__(self, key):
       
   407         """
       
   408         Retrieves the real value after stripping the prefix string (if
       
   409         present). If the prefix is present, pass the value through self.func
       
   410         before returning, otherwise return the raw value.
       
   411         """
       
   412         if key.startswith(self.prefix):
       
   413             use_func = True
       
   414             key = key[len(self.prefix):]
       
   415         else:
       
   416             use_func = False
       
   417         value = super(DictWrapper, self).__getitem__(key)
       
   418         if use_func:
       
   419             return self.func(value)
       
   420         return value
       
   421