from typing import (
    Any,
    Callable,
    Dict,
    Generic,
    Iterable, Iterator,
    Optional,
    Tuple, TypeVar, Type,
    Union
)
from typing_extensions import overload

T = TypeVar('T')
U = TypeVar('U')


def is_None(__value: Any) -> bool: ...
def is_not_None(__value: Any) -> bool: ...
def is_even(__value: Any) -> bool: ...
def is_odd(__value: Any) -> bool: ...
def is_iterable(__value: Any) -> bool: ...

def square(__value: Any) -> Any: ...
def double(__value: Any) -> Any: ...
def reciprocal(__value: Any) -> Any: ...
def rsub(__op1: Any, __op2: Any) -> Any: ...
def radd(__op1: Any, __op2: Any) -> Any: ...
def rmul(__op1: Any, __op2: Any) -> Any: ...
def rdiv(__op1: Any, __op2: Any) -> Any: ...
def rfdiv(__op1: Any, __op2: Any) -> Any: ...
def rpow(__op1: Any, __op2: Any) -> Any: ...
def rmod(__op1: Any, __op2: Any) -> Any: ...

def _parse_args(__tup: Tuple, __item: Any, __pos: int) -> Tuple: ...
def _parse_kwargs(__dct: Dict[str, Any], __item: Any) -> None: ...

def return_identity(__obj: Any) -> Any: ...
def return_first_arg(o: Any, *args, **kwargs) -> Any: ...
def return_called(__func: Callable) -> Any: ...

# def argmin(__iterable, *, key: Callable=None, default: Any=None) -> int: ...
# def argmax(__iterable, *, key: Callable=None, default: Any=None) -> int: ...
def all_distinct(__iterable: Iterable) -> bool: ...
def all_equal(__iterable: Iterable) -> bool: ...
def all_isinstance(iterable: Iterable, types: Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]) -> bool: ...
def all_monotone(iterable:Iterable, decreasing: bool=False, strict:bool=False) -> bool: ...
def any_isinstance(iterable: Iterable, types: Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]) -> bool: ...
def count_items(iterable: Iterable, pred: Callable=None, eq:bool=False) -> int: ...
def dotproduct(vec1: Iterable, vec2: Iterable) -> Any: ...
def groupedby(iterable: Iterable, key: Callable, keep: Callable=None, reduce:Callable=None, reducestart:Any=None) -> Dict: ...
# def minmax(__iterable: Iterable, *, key: Callable=None, default: Any=None) -> Tuple[Any, Any]: ...
def one(__iterable: Iterable) -> Any: ...
def partition(iterable: Iterable, pred: Callable=None) -> Tuple[Iterable, Iterable]: ...


class ItemIdxKey(Generic[T, U]):
    item: T
    idx: int
    key: U
    @overload
    def __new__(cls, item: T, idx: int) -> ItemIdxKey[T, T]: ...
    @overload
    def __new__(cls, item: T, idx: int, key: U) -> ItemIdxKey[T, U]: ...
    def __lt__(self, other: ItemIdxKey) -> bool: ...
    def __gt__(self, other: ItemIdxKey) -> bool: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class Seen:
    seenset: Optional[set]
    seenlist: Optional[list]
    def __new__(cls, seenset: set = None, seenlist: list = None) -> Seen: ...
    def __contains__(self, x: Any) -> bool: ...
    def __len__(self) -> int: ...
    def __eq__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...
    def contains_add(self, __o: Any) -> bool: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class chained:
    all: bool
    funcs: Tuple[Callable, ...]
    def __new__(cls, func0: Callable, *funcs: Callable, reverse:bool=False, all: bool=False) -> chained: ...
    def __call__(self, *args, **kwargs) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple[int]]: ...


class complement:
    func: Callable
    def __new__(cls, func: Callable) -> complement: ...
    def __call__(self, *args, **kwargs) -> bool: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class constant:
    item: Any
    def __new__(cls, item: Any) -> constant: ...
    def __call__(self, *args, **kwargs) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class flip:
    func: Callable
    def __new__(cls, x: Callable) -> flip: ...
    def __call__(self, *args, **kwargs) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class packed:
    func: Callable
    def __new__(cls, func: Callable) -> packed: ...
    def __call__(self, x: Tuple[Any, ...], **kwargs) -> Any: ...


class partial:
    args: Tuple
    func: Callable
    keywords: Dict[str, Any]
    num_placeholders: int
    _: Any
    def __new__(cls, func: Callable, *args, **kwargs) -> partial: ...
    def __call__(self, *args, **kwargs) -> Any: ...
    def __sizeof__(self) -> int: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...


class nth:
    n: int
    def __new__(cls, n: int) -> nth: ...
    def __call__(self, iterable: Iterable, default: Any=None, pred: Callable=None, truthy:bool=True, retpred: bool=False, retidx: bool=False) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...


class accumulate(Generic[T], Iterator[T]):
    current: T
    func: Callable[[T, T], T]
    @overload
    def __new__(cls, iterable: Iterable[T], func: Callable[[T, T], T] = None) -> accumulate[T]: ...
    @overload
    def __new__(cls, iterable: Iterable[T], func: Optional[Callable[[T, T], T]], start: T) -> accumulate[T]: ...
    def __iter__(self) -> accumulate[T]: ...
    def __next__(self) -> T: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...


class applyfunc:
    current: Any
    func: Callable
    def __new__(cls, func: Callable, initial: Any) -> applyfunc: ...
    def __iter__(self) -> applyfunc: ...
    def __next__(self) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class clamp:
    high: Any
    inclusive: bool
    low: Any
    remove: bool
    def __new__(cls, iterable: Any, low=None, high=None, inclusive=False, remove=True) -> clamp: ...
    def __iter__(self) -> clamp: ...
    def __next__(self) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class deepflatten:
    currentdepth: int
    depth: int
    ignore: Type
    types: Type
    def __new__(cls, iterable: Iterable, depth:int=-1, types:Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]=None, ignore:Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]=None) -> deepflatten: ...
    def __iter__(self) -> deepflatten: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class duplicates:
    key: Optional[Callable]
    seen: Seen
    def __new__(cls, iterable: Iterable, key: Callable=None) -> duplicates: ...
    def __iter__(self) -> duplicates: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class grouper:
    fillvalue: Any
    times: int
    truncate: bool
    @overload
    def __new__(cls, iterable: Iterable, n: int, *, truncate:bool=False) -> grouper: ...
    @overload
    def __new__(cls, iterable: Iterable, n: int, fillvalue: Any=None, truncate:bool=False) -> grouper: ...
    def __iter__(self) -> grouper: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class intersperse:
    fillvalue: Any
    def __new__(cls, iterable: Iterable, e: Any) -> intersperse: ...
    def __iter__(self) -> intersperse: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class iter_except:
    exception: Type[Exception]
    first: Callable
    func: Callable
    def __new__(cls, func: Callable, exception: Type[Exception], first: Callable=None) -> iter_except: ...
    def __iter__(self) -> iter_except: ...
    def __next__(self) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class merge:
    key: Callable
    reverse: bool
    def __new__(cls, *iterables: Iterable, key: Callable=None, reverse:bool=False) -> merge: ...
    def __iter__(self) -> merge: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class replicate:
    current: Any
    times: int
    timescurrent: int
    def __new__(cls, iterable: Iterable, times: int) -> replicate: ...
    def __iter__(self) -> replicate: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Union[Tuple[type, Tuple], Tuple[type, Tuple, Tuple]]: ...

class roundrobin:
    def __new__(cls, *args: Iterable) -> roundrobin: ...
    def __iter__(self) -> roundrobin: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class sideeffects:
    count: int
    func: Callable
    times: int
    def __new__(cls, iterable: Iterable, func: Callable, times:int=0) -> sideeffects: ...
    def __iter__(self) -> sideeffects: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class split:
    eq: bool
    keep: bool
    keep_after: bool
    keep_before: bool
    key: Any
    maxsplit: int
    @overload
    def __new__(cls, iterable: Iterable, key: Callable, maxsplit: int=-1, keep: bool=False, keep_before: bool=False, keep_after: bool=False) -> split: ...
    @overload
    def __new__(cls, iterable: Iterable, key: Any, maxsplit: int=-1, keep: bool=False, keep_before: bool=False, keep_after: bool=False, eq: bool=False) -> split: ...
    def __iter__(self) -> split: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Union[Tuple[type, Tuple], Tuple[type, Tuple, Tuple]]: ...

class starfilter:
    pred: Callable
    def __new__(cls, pred: Callable, iterable: Iterable) -> starfilter: ...
    def __iter__(self) -> starfilter: ...
    def __next__(self) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class successive:
    times: int
    def __new__(cls, iterable:Iterable, times: int=2) -> successive: ...
    def __iter__(self) -> successive: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Union[Tuple[type, Tuple], Tuple[type, Tuple, Tuple]]: ...

class tabulate:
    func: Callable
    current: Any
    def __new__(cls, func: Callable, start: Any=0) -> tabulate: ...
    def __iter__(self) -> tabulate: ...
    def __next__(self) -> Any: ...
    def __reduce__(self) -> Tuple[type, Tuple]: ...

class unique_everseen:
    key: Callable
    seen: Seen
    def __new__(cls, iterable: Iterable, key: Callable=None) -> unique_everseen: ...
    def __iter__(self) -> unique_everseen: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Tuple[type, Tuple, Tuple]: ...

class unique_justseen:
    key: Callable
    lastseen: Any
    def __new__(cls, iterable: Iterable, key: Callable=None) -> unique_justseen: ...
    def __iter__(self) -> unique_justseen: ...
    def __next__(self) -> Any: ...
    def __setstate__(self, state: Tuple) -> None: ...
    def __reduce__(self) -> Union[Tuple[type, Tuple], Tuple[type, Tuple, Tuple]]: ...
