from collections.abc import (
    Callable,
    Iterable,
    Iterator,
    Mapping,
    MutableMapping,
    MutableSet,
)
from typing import Any, Literal, TypeVar, overload
from typing_extensions import Self

_K = TypeVar("_K")
_V = TypeVar("_V")

class OrderedSet(MutableSet[_K]):
    dict: dict[_K, None] = ...
    @overload
    def __init__(self, iterable: Iterable[_K] | None) -> None: ...
    @overload
    def __init__(self, iterable: Iterable[Any] = ...) -> None: ...
    def __contains__(self, item: object) -> bool: ...
    def __iter__(self) -> Iterator[_K]: ...
    def __len__(self) -> int: ...
    def add(self, x: _K) -> None: ...
    def discard(self, item: _K) -> None: ...

class MultiValueDictKeyError(KeyError): ...

class MultiValueDict(MutableMapping[_K, _V]):
    @overload
    def __init__(
        self,
        key_to_list_mapping: Mapping[_K, list[_V] | None],
    ) -> None: ...
    @overload
    def __init__(
        self,
        key_to_list_mapping: Iterable[tuple[_K, list[_V]]],
    ) -> None: ...
    @overload
    def __init__(
        self,
        key_to_list_mapping: Iterable[Any] = ...,
    ) -> None: ...
    def getlist(self, key: _K, default: list[_V] | None = ...) -> list[_V]: ...
    def setlist(self, key: _K, list_: list[_V]) -> None: ...
    def setlistdefault(
        self, key: _K, default_list: list[_V] | None = ...
    ) -> list[_V]: ...
    def appendlist(self, key: _K, value: _V) -> None: ...
    def lists(self) -> Iterable[tuple[_K, list[_V]]]: ...
    def dict(self) -> dict[_K, _V | list[_V]]: ...
    def copy(self) -> Self: ...
    # These overrides are needed to convince mypy that this isn't an abstract class
    def __delitem__(self, item: _K) -> None: ...
    def __getitem__(self, item: _K) -> _V | Literal[[]]: ...  # type: ignore
    def __setitem__(self, k: _K, v: _V | list[_V]) -> None: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[_K]: ...

class ImmutableList(tuple[_V, ...]):
    warning: str = ...
    def __init__(self, *args: Any, warning: str = ..., **kwargs: Any) -> None: ...
    def __new__(cls, *args: Any, warning: str = ..., **kwargs: Any) -> Self: ...
    def complain(self, *wargs: Any, **kwargs: Any) -> None: ...

class DictWrapper(dict[str, _V]):
    func: Callable[[_V], _V] = ...
    prefix: str = ...
    @overload
    def __init__(
        self, data: Mapping[str, _V], func: Callable[[_V], _V], prefix: str
    ) -> None: ...
    @overload
    def __init__(
        self, data: Iterable[tuple[str, _V]], func: Callable[[_V], _V], prefix: str
    ) -> None: ...

class CaseInsensitiveMapping(Mapping[str, _V]):
    def __init__(self, data: Any) -> None: ...
    def __getitem__(self, key: str) -> Any: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[str]: ...
    def copy(self) -> Self: ...
