# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.

# %% auto 0
__all__ = ['P', 'VArgs', 'iscallattr', 'getbound', 'calldeco', 'callwith', 'callattr', 'attrfunc', 'applyfns']

# %% ../nbs/00_core.ipynb 6
from inspect import signature, ismethod, Signature
from functools import wraps

# %% ../nbs/00_core.ipynb 8
from typing import Any, Union, TypeAlias, ParamSpec, Callable, Sequence

# %% ../nbs/00_core.ipynb 10
#| export


# %% ../nbs/00_core.ipynb 12
import sigr

# %% ../nbs/00_core.ipynb 14
#| export


# %% ../nbs/00_core.ipynb 16
P = ParamSpec('P')
VArgs: TypeAlias = Union[Any, tuple]

# %% ../nbs/00_core.ipynb 17
def iscallattr(obj, attr: str) -> bool:
    return sigr.iscallattr(obj, attr)

# %% ../nbs/00_core.ipynb 18
def getbound(
    fn: Callable, *args: P.args, 
    __sig: Signature = Signature([]), __all: bool = False, 
    **kwargs: P.kwargs
) -> sigr.BoundReturn:
    __signature = kwargs.pop('__signature', __sig)
    __locals_if_empty = kwargs.pop('__locals_if_empty', __all)
    kwargs.update(__signature=__signature, __locals_if_empty=__locals_if_empty)
    return sigr.bind(fn, *args, __sig=__sig, __all=__all, **kwargs)

# %% ../nbs/00_core.ipynb 19
def calldeco(dec: Callable, fn: Callable | None = None, /, *args: P.args, **kwargs: P.kwargs) -> Callable:
    '''Decorates a function with the provided decorator and optional arguments.'''
    kwargs.update(__format=sigr.DecoratedFormat.infer(fn))
    return sigr.DecoratedFormat.format(dec, fn, *args, **kwargs)

# %% ../nbs/00_core.ipynb 20
def callwith(fn: Callable | None = None, /, *args: P.args, **kwargs: P.kwargs):
    '''Calls a function with a modified argument list that includes additional variable
    positional and keyword arguments.
    '''
    return sigr.callwith(fn, *args, **kwargs)

# %% ../nbs/00_core.ipynb 21
def callattr(obj, attr: str, *args: P.args, **kwargs: P.kwargs): 
    '''Calls a method of an object with filtered positional and keyword arguments.'''
    return sigr.callattr(obj, attr, *args, **kwargs)

# %% ../nbs/00_core.ipynb 22
def attrfunc(attr: str, *args: P.args, **kwargs: P.kwargs):
    '''Decorates a function to call an attribute of its first argument (assuming it is an object)
    with additional provided arguments.'''
    return sigr.attrfunc(attr, *args, **kwargs)

# %% ../nbs/00_core.ipynb 26
def applyfns(x, funcs: Sequence[Callable], *args: P.args, check: Callable | None = None, **kwargs: P.kwargs):   
    '''Applies a sequence of functions to an initial value `x`, optionally stopping 
    when a check function returns `True`.
    ''' 
    return sigr.applyfns(x, funcs, *args, check=check, **kwargs)
