| 251 | |
| 252 | |
| 253 | class ImmutableMultiDict(Mapping[_KeyType, _CovariantValueType]): |
| 254 | _dict: dict[_KeyType, _CovariantValueType] |
| 255 | |
| 256 | def __init__( |
| 257 | self, |
| 258 | *args: ImmutableMultiDict[_KeyType, _CovariantValueType] |
| 259 | | Mapping[_KeyType, _CovariantValueType] |
| 260 | | Iterable[tuple[_KeyType, _CovariantValueType]], |
| 261 | **kwargs: Any, |
| 262 | ) -> None: |
| 263 | assert len(args) < 2, "Too many arguments." |
| 264 | |
| 265 | value: Any = args[0] if args else [] |
| 266 | if kwargs: |
| 267 | value = ImmutableMultiDict(value).multi_items() + ImmutableMultiDict(kwargs).multi_items() |
| 268 | |
| 269 | if not value: |
| 270 | _items: list[tuple[Any, Any]] = [] |
| 271 | elif hasattr(value, "multi_items"): |
| 272 | value = cast(ImmutableMultiDict[_KeyType, _CovariantValueType], value) |
| 273 | _items = list(value.multi_items()) |
| 274 | elif hasattr(value, "items"): |
| 275 | value = cast(Mapping[_KeyType, _CovariantValueType], value) |
| 276 | _items = list(value.items()) |
| 277 | else: |
| 278 | value = cast("list[tuple[Any, Any]]", value) |
| 279 | _items = list(value) |
| 280 | |
| 281 | self._dict = {k: v for k, v in _items} |
| 282 | self._list = _items |
| 283 | |
| 284 | def getlist(self, key: Any) -> list[_CovariantValueType]: |
| 285 | return [item_value for item_key, item_value in self._list if item_key == key] |
| 286 | |
| 287 | def keys(self) -> KeysView[_KeyType]: |
| 288 | return self._dict.keys() |
| 289 | |
| 290 | def values(self) -> ValuesView[_CovariantValueType]: |
| 291 | return self._dict.values() |
| 292 | |
| 293 | def items(self) -> ItemsView[_KeyType, _CovariantValueType]: |
| 294 | return self._dict.items() |
| 295 | |
| 296 | def multi_items(self) -> list[tuple[_KeyType, _CovariantValueType]]: |
| 297 | return list(self._list) |
| 298 | |
| 299 | def __getitem__(self, key: _KeyType) -> _CovariantValueType: |
| 300 | return self._dict[key] |
| 301 | |
| 302 | def __contains__(self, key: Any) -> bool: |
| 303 | return key in self._dict |
| 304 | |
| 305 | def __iter__(self) -> Iterator[_KeyType]: |
| 306 | return iter(self.keys()) |
| 307 | |
| 308 | def __len__(self) -> int: |
| 309 | return len(self._dict) |
| 310 | |