from _typeshed import SupportsGetItem
from collections.abc import Callable, Hashable, Iterable, Mapping, MutableMapping, Sequence
from typing import Literal, overload, TypeGuard
from typing_extensions import TypeIs

__all__ = ("assoc", "assoc_in", "dissoc", "get_in", "itemfilter", "itemmap", "keyfilter", "keymap"
		, "merge", "merge_with", "update_in", "valfilter", "valmap")

@overload
def assoc[K: Hashable, V](d: Mapping[K, V], key: K, value: V, factory: Callable[[], dict[K, V]] = dict) -> dict[K, V]: ...
@overload
def assoc[K: Hashable, V](d: Mapping[K, V], key: K, value: V, factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...
def assoc[K: Hashable, V](d: Mapping[K, V], key: K, value: V, factory: Callable[[], MutableMapping[K, V]] = dict) -> MutableMapping[K, V]: ...

@overload
def assoc_in[K, V](d: Mapping[K, V], keys: Sequence[K], value: V) -> dict[K, V]: ...
@overload
def assoc_in[K, V](d: Mapping[K, V], keys: Sequence[K], value: V, factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...

@overload
def dissoc[K: Hashable, V](d: Mapping[K, V], *keys: K, factory: Callable[[], dict[K, V]] = dict) -> dict[K, V]: ...
@overload
def dissoc[K: Hashable, V](d: Mapping[K, V], *keys: K, factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...

@overload
def get_in[K: Hashable, V](keys: Sequence[K], coll: SupportsGetItem[K, V], default: None = None, no_default: Literal[True] = True) -> V: ...
@overload
def get_in[K: Hashable, V](keys: Sequence[K], coll: SupportsGetItem[K, V], default: None = None, no_default: bool = False) -> V | None: ...
@overload
def get_in[K: Hashable, V](keys: Sequence[K], coll: SupportsGetItem[K, V], default: V, no_default: bool = False) -> V: ...

@overload
def itemfilter[K0: Hashable, V0, K1: Hashable, V1](predicate: Callable[[tuple[K0, V0]], TypeIs[tuple[K1, V1]]], d: Mapping[K0, V0], factory: Callable[[], dict[K1, V1]] = dict) -> dict[K1, V1]: ...
@overload
def itemfilter[K0: Hashable, V0, K1: Hashable, V1](predicate: Callable[[tuple[K0, V0]], TypeGuard[tuple[K1, V1]]], d: Mapping[K0, V0], factory: Callable[[], dict[K1, V1]] = dict) -> dict[K1, V1]: ...
@overload
def itemfilter[K0: Hashable, V0](predicate: Callable[[tuple[K0, V0]], bool], d: Mapping[K0, V0], factory: Callable[[], dict[K0, V0]] = dict) -> dict[K0, V0]: ...
@overload
def itemfilter[K0: Hashable, V0, K1: Hashable, V1](predicate: Callable[[tuple[K0, V0]], TypeIs[tuple[K1, V1]]], d: Mapping[K0, V0], factory: Callable[[], MutableMapping[K1, V1]]) -> MutableMapping[K1, V1]: ...
@overload
def itemfilter[K0: Hashable, V0, K1: Hashable, V1](predicate: Callable[[tuple[K0, V0]], TypeGuard[tuple[K1, V1]]], d: Mapping[K0, V0], factory: Callable[[], MutableMapping[K1, V1]]) -> MutableMapping[K1, V1]: ...
@overload
def itemfilter[K0: Hashable, V0](predicate: Callable[[tuple[K0, V0]], bool], d: Mapping[K0, V0], factory: Callable[[], MutableMapping[K0, V0]]) -> MutableMapping[K0, V0]: ...
def itemfilter[K0: Hashable, V0, K1: Hashable, V1](predicate: Callable[[tuple[K0, V0]], bool] | Callable[[tuple[K0, V0]], TypeGuard[tuple[K1, V1]]] | Callable[[tuple[K0, V0]], TypeIs[tuple[K1, V1]]], d: Mapping[K0, V0], factory: Callable[[], MutableMapping[K1, V1]] = dict) -> MutableMapping[K1, V1]:
	...

@overload
def itemmap[K0: Hashable, V0, K1: Hashable, V1](func: Callable[[tuple[K0, V0]], tuple[K1, V1]], d: Mapping[K0, V0], factory: Callable[..., dict[K1, V1]] = dict) -> dict[K1, V1]: ...
@overload
def itemmap[K0: Hashable, V0, K1: Hashable, V1](func: Callable[[tuple[K0, V0]], tuple[K1, V1]], d: Mapping[K0, V0], factory: Callable[..., MutableMapping[K1, V1]]) -> MutableMapping[K1, V1]: ...
@overload
def itemmap[K0: Hashable, V0, K1: Hashable, V1](func: Callable[[tuple[K0, V0]], Iterable[K1 | V1]], d: Mapping[K0, V0], factory: Callable[..., dict[K1, V1]] = dict) -> dict[K1, V1]: ...
@overload
def itemmap[K0: Hashable, V0, K1: Hashable, V1](func: Callable[[tuple[K0, V0]], Iterable[K1 | V1]], d: Mapping[K0, V0], factory: Callable[..., MutableMapping[K1, V1]]) -> MutableMapping[K1, V1]: ...
def itemmap[K0: Hashable, V0, K1: Hashable, V1](func: Callable[[tuple[K0, V0]], tuple[K1, V1]] | Callable[[tuple[K0, V0]], Iterable[K1 | V1]], d: Mapping[K0, V0], factory: Callable[..., MutableMapping[K1, V1]] = dict) -> MutableMapping[K1, V1]:
	...

@overload
def keyfilter[K0: Hashable, K1: Hashable, V](predicate: Callable[[K0], TypeIs[K1]], d: Mapping[K0, V], factory: Callable[[], dict[K1, V]] = dict) -> dict[K1, V]: ...
@overload
def keyfilter[K0: Hashable, K1: Hashable, V](predicate: Callable[[K0], TypeGuard[K1]], d: Mapping[K0, V], factory: Callable[[], dict[K1, V]] = dict) -> dict[K1, V]: ...
@overload
def keyfilter[K0: Hashable, V](predicate: Callable[[K0], bool], d: Mapping[K0, V], factory: Callable[[], dict[K0, V]] = dict) -> dict[K0, V]: ...
@overload
def keyfilter[K0: Hashable, K1: Hashable, V](predicate: Callable[[K0], TypeIs[K1]], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K1, V]]) -> MutableMapping[K1, V]: ...
@overload
def keyfilter[K0: Hashable, K1: Hashable, V](predicate: Callable[[K0], TypeGuard[K1]], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K1, V]]) -> MutableMapping[K1, V]: ...
@overload
def keyfilter[K0: Hashable, V](predicate: Callable[[K0], bool], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K0, V]]) -> MutableMapping[K0, V]: ...
def keyfilter[K0: Hashable, K1: Hashable, V](predicate: Callable[[K0], bool] | Callable[[K0], TypeGuard[K1]] | Callable[[K0], TypeIs[K1]], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K1, V]] = dict) -> MutableMapping[K1, V]:
	...

@overload
def keymap[K0: Hashable, K1: Hashable, V](func: Callable[[K0], K1], d: Mapping[K0, V], factory: Callable[[], dict[K1, V]] = dict) -> dict[K1, V]: ...
@overload
def keymap[K0: Hashable, K1: Hashable, V](func: Callable[[K0], K1], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K1, V]]) -> MutableMapping[K1, V]: ...
def keymap[K0: Hashable, K1: Hashable, V](func: Callable[[K0], K1], d: Mapping[K0, V], factory: Callable[[], MutableMapping[K1, V]] = dict) -> MutableMapping[K1, V]:
	...

@overload
def merge[K: Hashable, V](*dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], dict[K, V]] = dict) -> dict[K, V]: ...
@overload
def merge[K: Hashable, V](*dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...
def merge[K: Hashable, V](*dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], MutableMapping[K, V]] = dict) -> MutableMapping[K, V]:
	...

@overload
def merge_with[K: Hashable, V](func: Callable[[Sequence[V]], V], *dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], dict[K, V]] = dict) -> dict[K, V]: ...
@overload
def merge_with[K: Hashable, V](func: Callable[[Sequence[V]], V], *dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...
def merge_with[K: Hashable, V](func: Callable[[Sequence[V]], V], *dicts: Mapping[K, V] | Iterable[Mapping[K, V]], factory: Callable[[], MutableMapping[K, V]] = dict) -> MutableMapping[K, V]:
	...

@overload
def update_in[K, V](d: Mapping[K, V], keys: Sequence[K], func: Callable[[V | None], V], default: None = None) -> dict[K, V]: ...
@overload
def update_in[K, V](d: Mapping[K, V], keys: Sequence[K], func: Callable[[V], V], default: V) -> dict[K, V]: ...
@overload
def update_in[K, V](d: Mapping[K, V], keys: Sequence[K], func: Callable[[V | None], V], default: None, factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...
@overload
def update_in[K, V](d: Mapping[K, V], keys: Sequence[K], func: Callable[[V], V], default: V, factory: Callable[[], MutableMapping[K, V]]) -> MutableMapping[K, V]: ...
def update_in[K, V](d: Mapping[K, V], keys: Sequence[K], func: Callable[[V], V], default: V | None = None, factory: Callable[[], MutableMapping[K, V]] = dict) -> MutableMapping[K, V]:
	...

@overload
def valfilter[K: Hashable, V0, V1](predicate: Callable[[V0], TypeIs[V1]], d: Mapping[K, V0], factory: Callable[[], dict[K, V1]] = dict) -> dict[K, V1]: ...
@overload
def valfilter[K: Hashable, V0, V1](predicate: Callable[[V0], TypeGuard[V1]], d: Mapping[K, V0], factory: Callable[[], dict[K, V1]] = dict) -> dict[K, V1]: ...
@overload
def valfilter[K: Hashable, V0](predicate: Callable[[V0], bool], d: Mapping[K, V0], factory: Callable[[], dict[K, V0]] = dict) -> dict[K, V0]: ...
@overload
def valfilter[K: Hashable, V0, V1](predicate: Callable[[V0], TypeIs[V1]], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V1]]) -> MutableMapping[K, V1]: ...
@overload
def valfilter[K: Hashable, V0, V1](predicate: Callable[[V0], TypeGuard[V1]], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V1]]) -> MutableMapping[K, V1]: ...
@overload
def valfilter[K: Hashable, V0](predicate: Callable[[V0], bool], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V0]]) -> MutableMapping[K, V0]: ...
def valfilter[K: Hashable, V0, V1](predicate: Callable[[V0], bool] | Callable[[V0], TypeGuard[V1]] | Callable[[V0], TypeIs[V1]], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V1]] = dict) -> MutableMapping[K, V1]:
	...

@overload
def valmap[K: Hashable, V0, V1](func: Callable[[V0], V1], d: Mapping[K, V0], factory: Callable[[], dict[K, V1]] = dict) -> dict[K, V1]: ...
@overload
def valmap[K: Hashable, V0, V1](func: Callable[[V0], V1], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V1]]) -> MutableMapping[K, V1]: ...
def valmap[K: Hashable, V0, V1](func: Callable[[V0], V1], d: Mapping[K, V0], factory: Callable[[], MutableMapping[K, V1]] = dict) -> MutableMapping[K, V1]:
	...

