Add headers.get and headers.getlist #180
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello there, first time contributing :)
I wanted to access a header value with little code, like
req.headers[b"content-type"]but since the headers are implemented as aSequencethere are no easy way beside iterating all the headers to find the one that interest me.I am not challenging the internal data-structure,
list(tuple(bytes, bytes, bytes))is kinda the only sane structure because of headers likeSet-Cookie.In this work I add two helpers
get(name) -> bytesandgetlist(name) -> list[bytes]that searches the headers for me, so I don't have to write thisnext(generator, None)everywhere 😄 The two method names at coined at theHeadersclass ofwerkzeug. We might also add thetype=parameter for total symmetry, you tell me.The implementation is simple stupid, it iterates over the headers looking for one that matches the name.
I did experiment with another implementation, as follow (didn't test it):
def __init__(self, full_items: List[Tuple[bytes, bytes, bytes]]) -> None: self._full_items = full_items + self._index = {} + for idx, (_, name, value) in enumerate(full_items): + self._index.setdefault(name, []).append(idx) def __bool__(self) -> bool: return bool(self._full_items) @@ -118,6 +133,15 @@ class Headers(Sequence[Tuple[bytes, bytes]]): _, name, value = self._full_items[idx] return (name, value) + def get(self, name: bytes, default: T = None) -> Union[bytes, T]: + try: + self[self._index[name][0]][1] + except KeyError: + return default + + def getlist(self, name: bytes) -> List[bytes]: + return [self[idx][1] for idx in self._index.get(name, ())]But I don't think it deserves an index. I think the O(n) search is fine.