def replace(self, key, value): """ Replace existing header with new value. If header doesn't exist this method work like ``__setitem__``. Replacing leads to deletion of all existing headers with the same name. """ key, value = to_bytestring_tuple(key, value) indices = [] for (i, (k, v)) in enumerate(self._items): if _keys_equal(k, key): indices.append(i) # If the key isn't present, this is easy: just append and abort early. if not indices: self._items.append((key, value)) return # Delete all but the first. I swear, this is the correct slicing # syntax! base_index = indices[0] for i in indices[:0:-1]: self._items.pop(i) del self._items[base_index] self._items.insert(base_index, (key, value))
def __init__(self, *args, **kwargs): # The meat of the structure. In practice, headers are an ordered list # of tuples. This early version of the data structure simply uses this # directly under the covers. # # An important curiosity here is that the headers are not stored in # 'canonical form', but are instead stored in the form they were # provided in. This is to ensure that it is always possible to # reproduce the original header structure if necessary. This leads to # some unfortunate performance costs on structure access where it is # often necessary to transform the data into canonical form on access. # This cost is judged acceptable in low-level code like `hyper`, but # higher-level abstractions should consider if they really require this # logic. self._items = [] for arg in args: self._items.extend([to_bytestring_tuple(*x) for x in arg]) for k, v in list(kwargs.items()): self._items.append(to_bytestring_tuple(k, v))
def __init__(self, *args, **kwargs): # The meat of the structure. In practice, headers are an ordered list # of tuples. This early version of the data structure simply uses this # directly under the covers. # # An important curiosity here is that the headers are not stored in # 'canonical form', but are instead stored in the form they were # provided in. This is to ensure that it is always possible to # reproduce the original header structure if necessary. This leads to # some unfortunate performance costs on structure access where it is # often necessary to transform the data into canonical form on access. # This cost is judged acceptable in low-level code like `hyper`, but # higher-level abstractions should consider if they really require this # logic. self._items = [] for arg in args: self._items.extend(map(lambda x: to_bytestring_tuple(*x), arg)) for k, v in kwargs.items(): self._items.append(to_bytestring_tuple(k, v))
def merge(self, other): """ Merge another header set or any other dict-like into this one. """ # Short circuit to avoid infinite loops in case we try to merge into # ourselves. if other is self: return if isinstance(other, HTTPHeaderMap): self._items.extend(other.iter_raw()) return for k, v in list(other.items()): self._items.append(to_bytestring_tuple(k, v))
def merge(self, other): """ Merge another header set or any other dict-like into this one. """ # Short circuit to avoid infinite loops in case we try to merge into # ourselves. if other is self: return if isinstance(other, HTTPHeaderMap): self._items.extend(other.iter_raw()) return for k, v in other.items(): self._items.append(to_bytestring_tuple(k, v))
def __setitem__(self, key, value): """ Unlike the dict __setitem__, this appends to the list of items. """ self._items.append(to_bytestring_tuple(key, value))