Skip to content
Merged
Changes from 15 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4adca90
add generics type parameters to ImmutableMultiDict
adriangb Jan 29, 2022
7994f31
Merge branch 'master' into generic-immutable-multi-dict
adriangb Jan 30, 2022
bb122b4
Merge branch 'master' into generic-immutable-multi-dict
adriangb Jan 31, 2022
7a9c286
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 1, 2022
309112b
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 3, 2022
33fa54b
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 8, 2022
d18674e
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 8, 2022
8149559
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 11, 2022
73dfd45
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 11, 2022
0213422
Merge branch 'master' into generic-immutable-multi-dict
adriangb Feb 16, 2022
6812f66
Merge branch 'master' into generic-immutable-multi-dict
adriangb Mar 21, 2022
e542551
Merge branch 'master' into generic-immutable-multi-dict
adriangb Apr 22, 2022
64c5398
Merge branch 'master' into generic-immutable-multi-dict
adriangb Apr 24, 2022
5884be8
Merge branch 'master' into generic-immutable-multi-dict
adriangb May 6, 2022
f7eccee
Merge branch 'master' into generic-immutable-multi-dict
adriangb May 22, 2022
2dda0de
rename type variables
adriangb May 23, 2022
932df88
fmt
adriangb May 23, 2022
c4b34ee
Merge remote-tracking branch 'upstream/master' into generic-immutable…
adriangb May 24, 2022
9ed2781
accept an iterable in the constructor
adriangb May 24, 2022
0e92359
remove get
adriangb May 24, 2022
76127b5
add test proving removing get works
adriangb May 24, 2022
6966ba6
make mypy happy
adriangb May 24, 2022
8396e57
Update starlette/datastructures.py
adriangb May 24, 2022
5261a1f
Update starlette/datastructures.py
adriangb May 24, 2022
e7631e8
fix comments
adriangb May 24, 2022
75a5e43
fmt
adriangb May 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions starlette/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class Address(typing.NamedTuple):
port: int


_T = typing.TypeVar("_T")
_KT = typing.TypeVar("_KT") # key type
_VT_co = typing.TypeVar("_VT_co", covariant=True) # value type for covariant containers

Comment thread
adriangb marked this conversation as resolved.

class URL:
def __init__(
self,
Expand Down Expand Up @@ -238,13 +243,15 @@ def __str__(self) -> str:
return ", ".join(repr(item) for item in self)


class ImmutableMultiDict(typing.Mapping):
class ImmutableMultiDict(typing.Mapping[_KT, _VT_co]):
_dict: typing.Dict[_KT, _VT_co]

def __init__(
self,
*args: typing.Union[
"ImmutableMultiDict",
typing.Mapping,
typing.List[typing.Tuple[typing.Any, typing.Any]],
"ImmutableMultiDict[_KT, _VT_co]",
typing.Mapping[_KT, _VT_co],
typing.Sequence[typing.Tuple[_KT, _VT_co]],

@Kludex Kludex May 23, 2022

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

],
**kwargs: typing.Any,
) -> None:
Expand All @@ -254,7 +261,7 @@ def __init__(
if kwargs:
value = (
ImmutableMultiDict(value).multi_items()
+ ImmutableMultiDict(kwargs).multi_items()
+ ImmutableMultiDict(kwargs).multi_items() # type: ignore[operator]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know the returned value of the operator + when there's a sum of two ImmutableMultiDict. That's why we ignore this error here.

)

if not value:
Expand All @@ -274,33 +281,43 @@ def __init__(
self._dict = {k: v for k, v in _items}
self._list = _items

def getlist(self, key: typing.Any) -> typing.List[typing.Any]:
def getlist(self, key: typing.Any) -> typing.List[_VT_co]:
return [item_value for item_key, item_value in self._list if item_key == key]

def keys(self) -> typing.KeysView:
def keys(self) -> typing.KeysView[_KT]:
return self._dict.keys()

def values(self) -> typing.ValuesView:
def values(self) -> typing.ValuesView[_VT_co]:
return self._dict.values()

def items(self) -> typing.ItemsView:
def items(self) -> typing.ItemsView[_KT, _VT_co]:
return self._dict.items()

def multi_items(self) -> typing.List[typing.Tuple[str, str]]:
def multi_items(self) -> typing.List[typing.Tuple[_KT, _VT_co]]:
return list(self._list)

def get(self, key: typing.Any, default: typing.Any = None) -> typing.Any:
@typing.overload
def get(self, key: _KT) -> _VT_co:
... # pragma: no cover

@typing.overload
def get(
self, key: _KT, default: typing.Optional[typing.Union[_VT_co, _T]] = ...
) -> typing.Union[_VT_co, _T]:
... # pragma: no cover

def get(self, key: _KT, default: typing.Any = None) -> typing.Any:
if key in self._dict:
return self._dict[key]
return default

def __getitem__(self, key: typing.Any) -> str:
def __getitem__(self, key: _KT) -> _VT_co:
return self._dict[key]

def __contains__(self, key: typing.Any) -> bool:
return key in self._dict

def __iter__(self) -> typing.Iterator[typing.Any]:
def __iter__(self) -> typing.Iterator[_KT]:
return iter(self.keys())

def __len__(self) -> int:
Expand All @@ -317,7 +334,7 @@ def __repr__(self) -> str:
return f"{class_name}({items!r})"


class MultiDict(ImmutableMultiDict):
class MultiDict(ImmutableMultiDict[typing.Any, typing.Any]):
def __setitem__(self, key: typing.Any, value: typing.Any) -> None:
self.setlist(key, [value])

Expand Down