"""
This type stub file was generated by pyright.
"""

from collections import UserList

from kombu.utils.functional import lazy

"""Functional-style utilities."""
__all__ = (
    "LRUCache",
    "is_list",
    "maybe_list",
    "memoize",
    "mlazy",
    "noop",
    "first",
    "firstmethod",
    "chunks",
    "padlist",
    "mattrgetter",
    "uniq",
    "regen",
    "dictfilter",
    "lazy",
    "maybe_evaluate",
    "head_from_fun",
    "maybe",
    "fun_accepts_kwargs",
)
FUNHEAD_TEMPLATE = ...

class DummyContext:
    def __enter__(self): ...
    def __exit__(self, *exc_info): ...

class mlazy(lazy):
    """Memoized lazy evaluation.

    The function is only evaluated once, every subsequent access
    will return the same value.
    """

    evaluated = ...
    _value = ...
    def evaluate(self): ...

def noop(*args, **kwargs):  # -> None:
    """No operation.

    Takes any arguments/keyword arguments and does nothing.
    """
    ...

def pass1(arg, *args, **kwargs):
    """Return the first positional argument."""
    ...

def evaluate_promises(it): ...
def first(predicate, it):  # -> Any | MethodType | None:
    """Return the first element in ``it`` that ``predicate`` accepts.

    If ``predicate`` is None it will return the first item that's not
    :const:`None`.
    """
    ...

def firstmethod(
    method, on_call=...
):  # -> (it: Unknown, *args: Unknown, **kwargs: Unknown) -> (Unknown | Any | None):
    """Multiple dispatch.

    Return a function that with a list of instances,
    finds the first instance that gives a value for the given method.

    The list can also contain lazy instances
    (:class:`~kombu.utils.functional.lazy`.)
    """
    ...

def chunks(it, n):  # -> Generator[list[Unknown], None, None]:
    """Split an iterator into chunks with `n` elements each.

    Warning:
        ``it`` must be an actual iterator, if you pass this a
        concrete sequence will get you repeating elements.

        So ``chunks(iter(range(1000)), 10)`` is fine, but
        ``chunks(range(1000), 10)`` is not.

    Example:
        # n == 2
        >>> x = chunks(iter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 2)
        >>> list(x)
        [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10]]

        # n == 3
        >>> x = chunks(iter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 3)
        >>> list(x)
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
    """
    ...

def padlist(container, size, default=...):
    """Pad list with default elements.

    Example:
        >>> first, last, city = padlist(['George', 'Costanza', 'NYC'], 3)
        ('George', 'Costanza', 'NYC')
        >>> first, last, city = padlist(['George', 'Costanza'], 3)
        ('George', 'Costanza', None)
        >>> first, last, city, planet = padlist(
        ...     ['George', 'Costanza', 'NYC'], 4, default='Earth',
        ... )
        ('George', 'Costanza', 'NYC', 'Earth')
    """
    ...

def mattrgetter(*attrs):  # -> (obj: Unknown) -> dict[Unknown, Any | None]:
    """Get attributes, ignoring attribute errors.

    Like :func:`operator.itemgetter` but return :const:`None` on missing
    attributes instead of raising :exc:`AttributeError`.
    """
    ...

def uniq(it):  # -> Generator[Unknown, None, None]:
    """Return all unique elements in ``it``, preserving order."""
    ...

def lookahead(it):  # -> zip_longest[tuple[Any, Any]]:
    """Yield pairs of (current, next) items in `it`.

    `next` is None if `current` is the last item.
    Example:
        >>> list(lookahead(x for x in range(6)))
        [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, None)]
    """
    ...

def regen(it):  # -> list[Unknown] | tuple[Unknown, ...] | _regen:
    """Convert iterator to an object that can be consumed multiple times.

    ``Regen`` takes any iterable, and if the object is an
    generator it will cache the evaluated list on first access,
    so that the generator can be "consumed" multiple times.
    """
    ...

class _regen(UserList, list):
    def __init__(self, it) -> None: ...
    def __reduce__(self): ...
    def __length_hint__(self): ...
    def __iter__(self): ...
    def __getitem__(self, index): ...
    def __bool__(self): ...
    @property
    def data(self): ...
    def __repr__(self): ...

def head_from_fun(fun, bound=..., debug=...):  # -> partial[Unknown] | str:
    """Generate signature function from actual function."""
    ...

def arity_greater(fun, n): ...
def fun_takes_argument(name, fun, position=...): ...
def METHOD_NAME(fun):  # -> bool:
    """Return true if function accepts arbitrary keyword arguments."""
    ...

def maybe(typ, val):
    """Call typ on value if val is defined."""
    ...

def seq_concat_item(seq, item):  # -> tuple[Unknown, ...]:
    """Return copy of sequence seq with item added.

    Returns:
        Sequence: if seq is a tuple, the result will be a tuple,
           otherwise it depends on the implementation of ``__add__``.
    """
    ...

def seq_concat_seq(a, b):  # -> Any:
    """Concatenate two sequences: ``a + b``.

    Returns:
        Sequence: The return value will depend on the largest sequence
            - if b is larger and is a tuple, the return value will be a tuple.
            - if a is larger and is a list, the return value will be a list,
    """
    ...