Closed
Labels
user-experienceEnsuring that users have a good experience using the libraryEnsuring that users have a good experience using the library
Description
Checklist
- I searched the HTTPX documentation but couldn't find what I'm looking for.
- I looked through similar issues on GitHub, but didn't find anything.
- I looked up "How to do ... in HTTPX" on a search engine and didn't find any information.
- I asked the community chat for help but didn't get an answer.
Question
presently Headers.keys returns a typing.List[str] rather than a (set-like) typing.KeysView[str], which appears to violate the Mapping protocol: https://docs.python.org/3/library/collections.abc.html#collections.abc.KeysView
this breaks code that expects set-like operations with Headers.keys, e.g.
dst: Dict[str, str] = ...
headers: httpx.Headers = ...
keys: Set[str] = {"set-cookie", "set-cookie2"}
dst.update({k: headers[k] for k in keys & headers.keys()})
is this an intentional design choice or simply an oversight?
Metadata
Metadata
Assignees
Labels
user-experienceEnsuring that users have a good experience using the libraryEnsuring that users have a good experience using the library
Activity
florimondmanca commentedon Apr 9, 2020
Not necessarily intentional, no. Any idea how we could return such a keyview object? I don't know how we can construct one from something that's not a dict.
florimondmanca commentedon Apr 9, 2020
Okay I found it — we can use
typing.KeysView(<dict>),typing.ValuesView(<dict>), etc.Thinking about this more, I think this was an intentional choice, basically to keep the scope down a bit.
Eg one reason why we cannot very easily implement these interfaces (eg building a dict and returning the result of calling
.keys()on it) is because duplicate headers are not forbidden by the HTTP spec.Set-Cookieis a prime example of this.That doesn't mean we can't implement the
KeysView/ValuesView/ItemsViewprotocols, though, but we'd need to implement our own subclasses, and basically end up with whatmultidictis doing. Making that work with type hints etc would be a significant chunk of code and work.Don't think we're ready to make that move yet… But I'd personally be interested in seeing what making this work would take.
obataku commentedon Apr 9, 2020
I think the easiest way would likely be something similar to how aiolibs
multidictdoes it, yeah; using the defaultKeysView,ValuesViewwouldn't work well for the reasons you mention although it's worth pointing out that theXViewconstructors accept general mappings (and using staledictsnapshots to implement the views would violate the protocol anyway).florimondmanca commentedon Apr 11, 2020
So, switching to
multidictis not as simple unfortunately, and probably not possible, because we already have some subtle behavior differences between ourQueryParamsandHeadersmodels, and how multidict behaves.Eg:
params[key]returns the first value in the list of items forkey, whilemultidictreturns the last.multidictdoesn't allow efficiently iterating over key-unique items (like a dict), so we have to dodict(md).keys()to get unique keys for queryparams (while multikeys is what headers expect).