mercurial/hgweb/request.py
changeset 36997 44467a4d472f
parent 36911 f0a851542a05
child 37049 55e901396005
equal deleted inserted replaced
36996:1bf555cb680e 36997:44467a4d472f
    26     Used to store parsed request parameters.
    26     Used to store parsed request parameters.
    27 
    27 
    28     This is inspired by WebOb's class of the same name.
    28     This is inspired by WebOb's class of the same name.
    29     """
    29     """
    30     def __init__(self):
    30     def __init__(self):
    31         # Stores (key, value) 2-tuples. This isn't the most efficient. But we
    31         self._items = {}
    32         # don't rely on parameters that much, so it shouldn't be a perf issue.
       
    33         # we can always add dict for fast lookups.
       
    34         self._items = []
       
    35 
    32 
    36     def __getitem__(self, key):
    33     def __getitem__(self, key):
    37         """Returns the last set value for a key."""
    34         """Returns the last set value for a key."""
    38         for k, v in reversed(self._items):
    35         return self._items[key][-1]
    39             if k == key:
       
    40                 return v
       
    41 
       
    42         raise KeyError(key)
       
    43 
    36 
    44     def __setitem__(self, key, value):
    37     def __setitem__(self, key, value):
    45         """Replace a values for a key with a new value."""
    38         """Replace a values for a key with a new value."""
    46         try:
    39         self._items[key] = [value]
    47             del self[key]
       
    48         except KeyError:
       
    49             pass
       
    50 
       
    51         self._items.append((key, value))
       
    52 
    40 
    53     def __delitem__(self, key):
    41     def __delitem__(self, key):
    54         """Delete all values for a key."""
    42         """Delete all values for a key."""
    55         oldlen = len(self._items)
    43         del self._items[key]
    56 
       
    57         self._items[:] = [(k, v) for k, v in self._items if k != key]
       
    58 
       
    59         if oldlen == len(self._items):
       
    60             raise KeyError(key)
       
    61 
    44 
    62     def __contains__(self, key):
    45     def __contains__(self, key):
    63         return any(k == key for k, v in self._items)
    46         return key in self._items
    64 
    47 
    65     def __len__(self):
    48     def __len__(self):
    66         return len(self._items)
    49         return len(self._items)
    67 
    50 
    68     def get(self, key, default=None):
    51     def get(self, key, default=None):
    71         except KeyError:
    54         except KeyError:
    72             return default
    55             return default
    73 
    56 
    74     def add(self, key, value):
    57     def add(self, key, value):
    75         """Add a new value for a key. Does not replace existing values."""
    58         """Add a new value for a key. Does not replace existing values."""
    76         self._items.append((key, value))
    59         self._items.setdefault(key, []).append(value)
    77 
    60 
    78     def getall(self, key):
    61     def getall(self, key):
    79         """Obtains all values for a key."""
    62         """Obtains all values for a key."""
    80         return [v for k, v in self._items if k == key]
    63         return self._items.get(key, [])
    81 
    64 
    82     def getone(self, key):
    65     def getone(self, key):
    83         """Obtain a single value for a key.
    66         """Obtain a single value for a key.
    84 
    67 
    85         Raises KeyError if key not defined or it has multiple values set.
    68         Raises KeyError if key not defined or it has multiple values set.
    86         """
    69         """
    87         vals = self.getall(key)
    70         vals = self._items[key]
    88 
       
    89         if not vals:
       
    90             raise KeyError(key)
       
    91 
    71 
    92         if len(vals) > 1:
    72         if len(vals) > 1:
    93             raise KeyError('multiple values for %r' % key)
    73             raise KeyError('multiple values for %r' % key)
    94 
    74 
    95         return vals[0]
    75         return vals[0]
    96 
    76 
    97     def asdictoflists(self):
    77     def asdictoflists(self):
    98         d = {}
    78         return {k: list(v) for k, v in self._items.iteritems()}
    99         for k, v in self._items:
       
   100             if k in d:
       
   101                 d[k].append(v)
       
   102             else:
       
   103                 d[k] = [v]
       
   104 
       
   105         return d
       
   106 
    79 
   107 @attr.s(frozen=True)
    80 @attr.s(frozen=True)
   108 class parsedrequest(object):
    81 class parsedrequest(object):
   109     """Represents a parsed WSGI request.
    82     """Represents a parsed WSGI request.
   110 
    83