mirror of https://github.com/encode/starlette.git
Ensure query params behavior matches standard mappings. (#338)
* QueryParams behavior as standard mapping
This commit is contained in:
parent
0c3a1e4a60
commit
774cb40a17
|
@ -231,7 +231,7 @@ class QueryParams(typing.Mapping[str, str]):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
params: typing.Mapping[str, str] = None,
|
||||
params: typing.Union["QueryParams", typing.Mapping[str, str]] = None,
|
||||
items: typing.List[typing.Tuple[str, str]] = None,
|
||||
query_string: str = None,
|
||||
scope: Scope = None,
|
||||
|
@ -241,6 +241,9 @@ class QueryParams(typing.Mapping[str, str]):
|
|||
assert items is None, "Cannot set both 'params' and 'items'"
|
||||
assert query_string is None, "Cannot set both 'params' and 'query_string'"
|
||||
assert scope is None, "Cannot set both 'params' and 'scope'"
|
||||
if isinstance(params, QueryParams):
|
||||
_items = list(params.multi_items())
|
||||
else:
|
||||
_items = list(params.items())
|
||||
elif items is not None:
|
||||
assert query_string is None, "Cannot set both 'items' and 'query_string'"
|
||||
|
@ -252,25 +255,27 @@ class QueryParams(typing.Mapping[str, str]):
|
|||
elif scope is not None:
|
||||
_items = parse_qsl(scope["query_string"].decode("latin-1"))
|
||||
|
||||
self._dict = {k: v for k, v in reversed(_items)}
|
||||
self._dict = {k: v for k, v in _items}
|
||||
self._list = _items
|
||||
|
||||
def getlist(self, key: typing.Any) -> typing.List[str]:
|
||||
return [item_value for item_key, item_value in self._list if item_key == key]
|
||||
|
||||
def keys(self) -> typing.List[str]: # type: ignore
|
||||
return [key for key, value in self._list]
|
||||
return list(self._dict.keys())
|
||||
|
||||
def values(self) -> typing.List[str]: # type: ignore
|
||||
return [value for key, value in self._list]
|
||||
return list(self._dict.values())
|
||||
|
||||
def items(self) -> typing.List[typing.Tuple[str, str]]: # type: ignore
|
||||
return list(self._dict.items())
|
||||
|
||||
def multi_items(self) -> typing.List[typing.Tuple[str, str]]:
|
||||
return list(self._list)
|
||||
|
||||
def get(self, key: typing.Any, default: typing.Any = None) -> typing.Any:
|
||||
if key in self._dict:
|
||||
return self._dict[key]
|
||||
else:
|
||||
return default
|
||||
|
||||
def __getitem__(self, key: typing.Any) -> str:
|
||||
|
@ -283,7 +288,7 @@ class QueryParams(typing.Mapping[str, str]):
|
|||
return iter(self.keys())
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._list)
|
||||
return len(self._dict)
|
||||
|
||||
def __eq__(self, other: typing.Any) -> bool:
|
||||
if not isinstance(other, QueryParams):
|
||||
|
|
|
@ -172,15 +172,16 @@ def test_queryparams():
|
|||
assert "a" in q
|
||||
assert "A" not in q
|
||||
assert "c" not in q
|
||||
assert q["a"] == "123"
|
||||
assert q.get("a") == "123"
|
||||
assert q["a"] == "456"
|
||||
assert q.get("a") == "456"
|
||||
assert q.get("nope", default=None) is None
|
||||
assert q.getlist("a") == ["123", "456"]
|
||||
assert q.keys() == ["a", "a", "b"]
|
||||
assert q.values() == ["123", "456", "789"]
|
||||
assert q.items() == [("a", "123"), ("a", "456"), ("b", "789")]
|
||||
assert list(q) == ["a", "a", "b"]
|
||||
assert dict(q) == {"a": "123", "b": "789"}
|
||||
assert q.keys() == ["a", "b"]
|
||||
assert q.values() == ["456", "789"]
|
||||
assert q.items() == [("a", "456"), ("b", "789")]
|
||||
assert len(q) == 2
|
||||
assert list(q) == ["a", "b"]
|
||||
assert dict(q) == {"a": "456", "b": "789"}
|
||||
assert str(q) == "a=123&a=456&b=789"
|
||||
assert repr(q) == "QueryParams(query_string='a=123&a=456&b=789')"
|
||||
assert QueryParams({"a": "123", "b": "456"}) == QueryParams(
|
||||
|
@ -193,4 +194,10 @@ def test_queryparams():
|
|||
{"b": "456", "a": "123"}
|
||||
)
|
||||
assert QueryParams() == QueryParams({})
|
||||
assert QueryParams(items=[("a", "123"), ("a", "456")]) == QueryParams(
|
||||
query_string="a=123&a=456"
|
||||
)
|
||||
assert QueryParams({"a": "123", "b": "456"}) != "invalid"
|
||||
|
||||
q = QueryParams(items=[("a", "123"), ("a", "456")])
|
||||
assert QueryParams(q) == q
|
||||
|
|
Loading…
Reference in New Issue