# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/40_duck.ipynb.

# %% auto 0
__all__ = ['iterable', 'itertype', 'iterq', 'listq', 'tupleq', 'nlen', 'len1', 'len2', 'len3', 'len4', 'npbool', 'boolic',
           'bool01', 'bools', 'boolq', 'intq', 'ints', 'floatq', 'floats', 'real', 'realq', 'reals', 'num', 'numq',
           'nums', 'numstr', 'numstrq', 'none', 'notnone', 'na', 'anyq', 'pynan', 'pdna', 'npnan', 'nan', 'nanq',
           'nans', 'pattern', 'rematch', 'strtmpl', 'patternq', 'nilstr', 'notnilstr', 'strbytes', 'notstrbytes',
           'notiterstr', 'strq', 'strs', 'ospathlike', 'plibpath', 'posixpath', 'pathlike', 'pathq', 'paths',
           'walktuple', 'walkparts', 'moduleloader', 'modulespec', 'moduletype', 'wrappertype', 'builtinfunctype',
           'trackbacktype', 'functiontype', 'mapping', 'moduleq', 'callq', 'literal', 'enumauto', 'enumdict',
           'dictkeys', 'dictvalues', 'dictitems', 'setq', 'dictq', 'sig', 'param', 'paramkind', 'logger', 'loggerq',
           'ichain', 'iprod', 'ziplong', 'artist', 'colormap', 'lcolormap', 'lscolormap', 'mplpatch', 'mplaxbase',
           'mplaxes', 'nparray', 'npmatrix', 'recarray', 'npempty', 'npdatasource', 'sparray', 'spmatrix', 'cscarray',
           'cscmatrix', 'cooarray', 'coomatrix', 'csrarray', 'csrmatrix', 'diaarray', 'diamatrix', 'dokarray',
           'dokmatrix', 'lilarray', 'lilmatrix', 'bsrarray', 'bsrmatrix', 'sparsearray', 'sparsematrix', 'sparse',
           'array', 'matrix', 'sparseq', 'arrayq', 'matrixq', 'cv2vidcap', 'pilimage', 'vidcap', 'image', 'groupkey',
           'pddelegate', 'pdcataccessor', 'pdindex', 'pdcatindex', 'pdseries', 'boolindex', 'catindex', 'boolindexq',
           'catindexq', 'indextype', 'indexlike', 'seriestype', 'serieslike', 'pddataframe', 'dataframe', 'pttype',
           'pttypeq', 'memfmt', 'presfmt', 'ptsize', 'ptsizeq', 'ptdevice', 'ptdeviceq', 'pttensor', 'inttensor',
           'booltensor', 'floattensor', 'longtensor', 'doubletensor', 'pttensorq', 'inttensorq', 'booltensorq',
           'floattensorq', 'longtensorq', 'doubletensorq', 'nantensor', 'nantensorq', 'tensor', 'tensorq', 'ptmodule',
           'plmodule', 'nnmodule', 'ptdataset', 'pldatamodule', 'ptdataloader', 'neuralode', 'neuralsde',
           'neuraldynamics', 'augmenter', 'odefunc', 'sdefunc', 'sdeito', 'brownianintervial', 'dtype', 'dtypeq',
           'device', 'deviceq', 'devcpu', 'devmps', 'devcuda', 'size', 'sizeq', 'datasource', 'adata', 'adatas',
           'graphtype', 'datatype', 'nnum', 'nint', 'nfloat', 'int2', 'int3', 'int4', 'shaped', 'dimmed', 'dim1',
           'dim2', 'dim3', 'dim4', 'genset', 'setstr', 'setnum', 'kvdict', 'pttndict', 'annreturn', 'slicelike',
           'slicespec', 'slicespecs', 'richtree', 'richtext', 'richcons', 'richprog', 'richtask', 'tqdmauto',
           'typerapp']

# %% ../nbs/40_duck.ipynb 6
from enum import member, _EnumDict

# %% ../nbs/40_duck.ipynb 8
from types import FunctionType
from typing import (
    Any, Dict, List, Set, Self, Type, Union, Tuple, Generic, Callable, Literal, 
    TypeVar, ClassVar, TypeAlias, ParamSpec, Optional,
    Iterable, ForwardRef, Mapping, TypeGuard, Generic, Protocol
)

# %% ../nbs/40_duck.ipynb 10
#| export

# %% ../nbs/40_duck.ipynb 12
#| export

# %% ../nbs/40_duck.ipynb 14
from quac.cons import (
    NIL, NDIM, SHAPE, KEYS, VALUES, __K__, __V__, __N__, __RETANNOT__, __KVTYPES__,
    __D__, __LIT__, __LITNAME__, __EMPTYVAL__, __DEV__
)
from .type import T, Ts, O, P
from .enum import Species
from .base import Duck
from .misc import getretann
from . import grds, eggs

# %% ../nbs/40_duck.ipynb 17
class iterable(Duck, Generic[*Ts]):
    '''`typings.Iterable`, `collections.abc.Iterable`'''
    __ducktype__ = (Iterable, eggs.c_iterable, )
    __generate__ = lambda: ()
    
    
class itertype(iterable, Generic[*Ts]):
    '''iterable type (i.e. `Iterable`, `list`, or `tuple`)'''
    __ducktype__ = (iterable, list, tuple)
    __generate__ = lambda: ()

# %% ../nbs/40_duck.ipynb 18
class iterq(itertype, Generic[*Ts]):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 21
class listq(Duck[list[T]]):
    __ducktype__ = (list, )
    __species__ = Species.OPT

class tupleq(Duck[tuple]):
    __ducktype__ = (tuple, )
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 24
from typing import Any
class nlen(itertype[*Ts], Duck):
    '''A ducktype for iterables with a specific length'''
    __n__: ClassVar[int] = 0
    __emptyval__: ClassVar[Any] = 0
    
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        n = cls.__n__
        e = cls.__emptyval__
        islen = grds._islen(cls)
        cls.__expected__.update(__len__=n)
        cls.__extrafns__.update(__len__=islen)        
        cls.__generate__ = lambda: (e, ) * n
        return cls

# %% ../nbs/40_duck.ipynb 25
class len1(nlen[*Ts]):
    '''A ducktype for iterables with length 1'''
    __n__: ClassVar[int] = 1

class len2(nlen[*Ts]):
    '''A ducktype for iterables with length 2'''
    __n__: ClassVar[int] = 2

class len3(nlen[*Ts]):
    '''A ducktype for iterables with length 3'''
    __n__: ClassVar[int] = 3

class len4(nlen[*Ts]):
    '''A ducktype for iterables with length 4'''
    __n__: ClassVar[int] = 4

# %% ../nbs/40_duck.ipynb 30
class npbool(Duck): 
    '''`np.bool_`'''
    __ducktype__ = (eggs.np_bool, )

class boolic(npbool): 
    '''`bool`, `np.bool_`'''
    __ducktype__ = (eggs.np_bool, bool,)

class bool01(Duck):
    '''`bool`, `np.bool_`, `0`, `1`'''
    __ducktype__ = (boolic, 0, 1)
    
class bools(itertype[*Ts]):
    '''list of bool01'''
    __expected__ = dict(dtype=bool01)

# %% ../nbs/40_duck.ipynb 31
class boolq(bool01):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 35
class intq(Duck):
    '''`int` or None'''
    __ducktype__ = (int, )
    __species__ = Species.OPT
    
class ints(itertype[*Ts], Generic[*Ts]):
    '''iterable of `int`s'''
    __expected__ = dict(dtype=int)

# %% ../nbs/40_duck.ipynb 37
class floatq(Duck):
    '''`float` or None'''
    __ducktype__ = (float, )
    __species__ = Species.OPT
    
class floats(itertype[*Ts], Generic[*Ts]):
    '''iterable of `float`s'''
    __expected__ = dict(dtype=float)

# %% ../nbs/40_duck.ipynb 39
class real(Duck):
    '''R (i.e. `int` or `float`)'''
    __ducktype__ = (int, float, )
    
class realq(real):
    '''`real` or None'''
    __species__ = Species.OPT
    
class reals(itertype[*Ts], Generic[*Ts]):
    '''iterable of `real`'''
    __expected__ = dict(dtype=real)

# %% ../nbs/40_duck.ipynb 41
class num(Duck):
    '''`int`, `float`, `complex`, or `Number`'''
    __ducktype__ = (int, float, complex, eggs.n_number)
    
class numq(num):
    '''`real` or None'''
    __species__ = Species.OPT
    
class nums(itertype[*Ts], Generic[*Ts]):
    '''iterable of `num`'''
    __expected__ = dict(dtype=num)

# %% ../nbs/40_duck.ipynb 45
class numstr(Duck):
    '''`num` or str'''
    __ducktype__ = (num, str,)

# %% ../nbs/40_duck.ipynb 46
class numstrq(numstr):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 49
class none(Duck): 
    '''`None` or `NoneType`'''
    __ducktype__ = (None, eggs.t_nonetype)
    
class notnone(none): 
    '''not `None` or `NoneType`'''
    __species__ = Species.NOT
    
class na(Duck): 
    '''`NA` or `NAType`'''
    __ducktype__ = (eggs.pd_na, eggs.pd_natype,)

# %% ../nbs/40_duck.ipynb 50
class anyq(notnone[T]):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 52
class pynan(Duck): 
    '''`math.nan`''';
    __ducktype__ = (eggs.m_nan, )
    
class pdna(Duck): 
    '''`pd.NA`''';
    __ducktype__ = (
        eggs.pd_na, 
    )

class npnan(Duck): 
    '''`np.nan`, `np.NaN`, or `np.NAN`'''
    __ducktype__ = (
        eggs.np_nan, eggs.np_NaN, eggs.np_NAN, 
    )

# %% ../nbs/40_duck.ipynb 53
class nan(Duck):
    '''`math.nan`, `pd.NA`, `np.nan`, `np.NaN`, or `np.NAN`'''
    __ducktype__ = (
        eggs.m_nan, eggs.np_nan, eggs.np_NaN, eggs.np_NAN, 
        eggs.pd_na,# eggs.pd_natype, #float('nan')
    )
    
class nanq(Duck):
    '''`nan` or None'''
    __ducktype__ = (nan, )
    __species__ = Species.OPT
    
class nans(Duck):
    '''iterable of `nan`'''
    __ducktype__ = (itertype,)
    __expected__ = dict(dtype=nan)

# %% ../nbs/40_duck.ipynb 60
class pattern(Duck): 
    '''`re.Pattern`'''
    __ducktype__ = (eggs.re_pattern, )

class rematch(Duck): 
    '''`re.Match`'''
    __ducktype__ = (eggs.re_match, )

class strtmpl(Duck): 
    '''`string.Template`'''
    __ducktype__ = (eggs.s_template, )

# %% ../nbs/40_duck.ipynb 61
class patternq(pattern):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 63
class nilstr(Duck):
    '''`''` (the nil string)'''
    __ducktype__ = (NIL, )
    __guard__ = lambda x: x == NIL
    
class notnilstr(nilstr): 
    '''not `nilstr` (not `''`, the nil string)'''
    __species__ = Species.NOT

# %% ../nbs/40_duck.ipynb 64
class strbytes(Duck):
    '''str or bytes'''
    __ducktype__ = (str, bytes)
    
class notstrbytes(strbytes): 
    '''not (str or bytes)'''
    __species__ = Species.NOT
    

class notiterstr(itertype[*Ts], Generic[*Ts]):
    '''An iterable but not of `strbytes`'''
    # __ducktype__ = (itertype, )
    @classmethod
    def __guard__(cls, x):
        return super().__guard__(x) and notstrbytes(x)

# %% ../nbs/40_duck.ipynb 65
class strq(Duck): 
    '''`str` or None'''
    __ducktype__ = (str, )
    __species__ = Species.OPT

class strs(Duck): 
    '''iterable of `str`'''
    __ducktype__ = (itertype, notstrbytes, )
    __expected__ = dict(dtype=str)

# %% ../nbs/40_duck.ipynb 68
class ospathlike(Duck):
    '''`os.PathLike`'''
    __ducktype__ = (eggs.os_pathlike, )

class plibpath(Duck):
    '''`pathlib.Path`'''
    __ducktype__ = (eggs.pl_path, )

class posixpath(Duck):
    '''`pathlib.PosixPath`'''
    __ducktype__ = (eggs.pl_posixpath, )

# %% ../nbs/40_duck.ipynb 70
class pathlike(Duck, Generic[*Ts]):
    '''`os.PathLike`, `pathlib.Path`, `pathlib.PosixPath`'''
    __ducktype__ = (str, bytes, eggs.os_pathlike, eggs.pl_path, eggs.pl_posixpath)    

# %% ../nbs/40_duck.ipynb 71
class pathq(pathlike, Generic[*Ts]):
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 73
class paths(notiterstr):
    '''A type alias for a list of paths.'''
    __expected__ = dict(dtype=pathlike)

# %% ../nbs/40_duck.ipynb 75
class walktuple(len3, itertype[pathlike, paths, paths]):
    '''A type alias for a tuple from `os.walkdir` i.e. `(dirpath, dirnames, filenames)`.'''
    __expected__ = dict(dtype=pathlike)
    @classmethod
    def __guard__(cls, obj: Any) -> bool:
        return grds.istuple(obj) and len(obj) == 3 and pathlike(obj[0]) and all(paths(*obj[1:]))
    
class walkparts(itertype[walktuple]):
    '''A type alias for an iterable of walk tuples from `os.walkdir` 
    i.e. `Iterable[(dirpath, dirnames, filenames), ...]`.'''
    __expected__ = dict(dtype=walktuple)

# %% ../nbs/40_duck.ipynb 77
class moduleloader(Duck):
    '''`importlib.Loader`'''
    __ducktype__ = (eggs.il_moduleloader, )
    
class modulespec(Duck):
    '''`importlib.machinery.ModuleSpec`'''
    __ducktype__ = (eggs.il_modulespec, )

# %% ../nbs/40_duck.ipynb 79
class moduletype(Duck):
    '''`types.ModuleType`'''
    __ducktype__ = (eggs.t_moduletype, )
    
class wrappertype(Duck):
    '''`types.MethodWrapperType`'''
    __ducktype__ = (eggs.t_methodwrappertype, )
    
class builtinfunctype(Duck):
    '''`types.BuiltinFunctionType`'''
    __ducktype__ = (eggs.t_builtinfunctiontype, )
    
class trackbacktype(Duck):
    '''`types.TracebackType`'''
    __ducktype__ = (eggs.t_tracebacktype, )
    
class functiontype(Duck):
    '''`types.FunctionType`'''
    __ducktype__ = (eggs.t_functiontype, )
    
class mapping(Duck):
    '''`collections.Mapping`'''
    __ducktype__ = (eggs.c_mapping, )
    

# %% ../nbs/40_duck.ipynb 80
class moduleq(moduletype, Generic[T]):
    '''`Optional[types.ModuleType]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 82
class callq(Duck[Callable[P, T]]):
    '''`Optional[Callable[P, T]]`'''
    __ducktype__ = (Callable, )
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 84
class literal(Duck[T]):
    '''`typing.Literal`'''
    __ducktype__ = (Literal, str, )
    __lit__: ClassVar[Optional[T]] = None
    __litname__: ClassVar[bool] = True
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        __lit__ = kwargs.get(__LIT__, getattr(cls, __LIT__, None))
        __name__ = f'[{__lit__}]'
        rename = getattr(cls, __LITNAME__, True)
        namespace.update(__lit__=__lit__)
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        setattr(cls, __LIT__, __lit__)
        isval = lambda obj, val: val == __lit__
        cls.__expected__.update(__lit__=__lit__)
        cls.__extrafns__.update(__lit__=isval)
        if rename: cls.__name__ = __name__
        return cls

# %% ../nbs/40_duck.ipynb 86
class enumauto(Duck[member]):
    '''A type alias for an `auto()` generated enum `member`.'''
    __ducktype__ = (member, )

class enumdict(Duck[_EnumDict]):
    '''A type alias for `_EnumDict`.'''
    __ducktype__ = (_EnumDict, )

# %% ../nbs/40_duck.ipynb 88
class dictkeys(Duck):
    '''`_collections_abc.dict_keys`'''
    __ducktype__ = (eggs.c_dict_keys, )
    
class dictvalues(Duck):
    '''`_collections_abc.dict_values`'''
    __ducktype__ = (eggs.c_dict_values, )
    
class dictitems(Duck):
    '''`_collections_abc.dict_items`'''
    __ducktype__ = (eggs.c_dict_items, )

# %% ../nbs/40_duck.ipynb 89
class setq(Duck[set]):
    '''`Optional[set]`'''
    __ducktype__ = (set, )
    __species__ = Species.OPT
    
class dictq(Duck[dict[T, O]]):
    '''`Optional[dict]`'''
    __ducktype__ = (dict, )
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 91
class sig(Duck):
    '''`inspect.Signature`'''
    __ducktype__ = (eggs.i_sig, )
    
class param(Duck):
    '''`inspect.Parameter`'''
    __ducktype__ = (eggs.i_param, )
    
class paramkind(Duck):
    '''`inspect._ParameterKind`'''
    __ducktype__ = (eggs.i_paramkind, )

# %% ../nbs/40_duck.ipynb 93
class logger(Duck):
    '''`logging.Logger`'''
    __ducktype__ = (eggs.l_logger, )
    
    
class loggerq(logger):
    '''`Optional[logging.Logger]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 95
class ichain(Duck):
    '''`itertools.chain`'''
    __ducktype__ = (eggs.it_chain, )
    
class iprod(Duck):
    '''`itertools.product`'''
    __ducktype__ = (eggs.it_prod, )
    
class ziplong(Duck):
    '''`itertools.zip_longest`'''
    __ducktype__ = (eggs.it_ziplong, )

# %% ../nbs/40_duck.ipynb 98
class _mpl_base(Duck):
    '''`matplotlib.axes._base`''';
    __ducktype__ = (eggs._mpl_base, )
    
class _mpl_axes(Duck):
    '''`matplotlib.axes._axes`''';
    __ducktype__ = (eggs._mpl_axes, )
    

class artist(Duck): 
    '''`matplotlib.artist.Artist`'''
    __ducktype__ = (eggs.mpl_artist, )
    
class colormap(Duck): 
    '''`matplotlib.colors.Colormap`'''
    __ducktype__ = (eggs.mpl_colormap, )

class lcolormap(Duck): 
    '''`matplotlib.colors.ListedColormap`'''
    __ducktype__ = (eggs.mpl_lcolormap, )
    
class lscolormap(Duck): 
    '''`matplotlib.colors.LinearSegmentedColormap`'''
    __ducktype__ = (eggs.mpl_lscolormap, )
    
class mplpatch(Duck): 
    '''`matplotlib.patches.Patch`'''
    __ducktype__ = (eggs.mpl_patch, )

class mplaxbase(Duck): 
    '''`matplotlib.axes._base._AxesBase`'''
    __ducktype__ = (eggs.mpl_axbase, )

class mplaxes(Duck): 
    '''`matplotlib.axes._axes.Axes`'''
    __ducktype__ = (eggs.mpl_axes, )
    

# %% ../nbs/40_duck.ipynb 101
class nparray(Duck, Generic[*Ts]): 
    '''`numpy.ndarray`''';
    __ducktype__ = (eggs.np_array, )
    
class npmatrix(Duck, Generic[*Ts]): 
    '''`numpy.matrix`''';
    __ducktype__ = (eggs.np_matrix, )

class recarray(Duck, Generic[*Ts]): 
    '''`numpy.recarray`''';
    __ducktype__ = (eggs.np_recarray, )
    
class npempty(Duck):
    '''`numpy.empty`''';
    __ducktype__ = (eggs.np_empty, )

# %% ../nbs/40_duck.ipynb 102
class npdatasource(Duck): 
    '''`numpy.DataSource`''';
    __ducktype__ = (eggs.np_datasource, )

# %% ../nbs/40_duck.ipynb 104
class sparray(Duck, Generic[*Ts]): 
    '''`scipy.sparse.aparray`''';
    __ducktype__ = (eggs.sp_sparray, )

class spmatrix(Duck, Generic[*Ts]): 
    '''`scipy.sparse.spmatrix`''';
    __ducktype__ = (eggs.sp_spmatrix, )
    

# %% ../nbs/40_duck.ipynb 106
class cscarray(Duck):
    '''`scipy.sparse.csc_array`''';
    __ducktype__ = (eggs.sp_csc_array, )
    
class cscmatrix(Duck):
    '''`scipy.sparse.csc_matrix`''';
    __ducktype__ = (eggs.sp_csc_matrix, )

class cooarray(Duck):
    '''`scipy.sparse.coo_array`''';
    __ducktype__ = (eggs.sp_coo_array, )

class coomatrix(Duck):
    '''`scipy.sparse.coo_matrix`''';
    __ducktype__ = (eggs.sp_coo_matrix, )

class csrarray(Duck):
    '''`scipy.sparse.csr_array`''';
    __ducktype__ = (eggs.sp_csr_array, )

class csrmatrix(Duck):
    '''`scipy.sparse.csr_matrix`''';
    __ducktype__ = (eggs.sp_csr_matrix, )

class diaarray(Duck):
    '''`scipy.sparse.dia_array`''';
    __ducktype__ = (eggs.sp_dia_array, )

class diamatrix(Duck):
    '''`scipy.sparse.dia_matrix`''';
    __ducktype__ = (eggs.sp_dia_matrix, )

class dokarray(Duck):
    '''`scipy.sparse.dok_array`''';
    __ducktype__ = (eggs.sp_dok_array, )

class dokmatrix(Duck):
    '''`scipy.sparse.dok_matrix`''';
    __ducktype__ = (eggs.sp_dok_matrix, )

class lilarray(Duck):
    '''`scipy.sparse.lil_array`''';
    __ducktype__ = (eggs.sp_lil_array, )

class lilmatrix(Duck):
    '''`scipy.sparse.lil_matrix`''';
    __ducktype__ = (eggs.sp_lil_matrix, )

class bsrarray(Duck):
    '''`scipy.sparse.bsr_array`''';
    __ducktype__ = (eggs.sp_bsr_array, )

class bsrmatrix(Duck):
    '''`scipy.sparse.bsr_matrix`''';
    __ducktype__ = (eggs.sp_bsr_matrix, )

# %% ../nbs/40_duck.ipynb 108
class sparsearray(Duck, Generic[*Ts]): 
    '''sparse array (e.g. 
    `scipy.sparse.sparray`, `scipy.sparse.cscarray`, `scipy.sparse.cooarray`, 
    `scipy.sparse.csrarray`, `scipy.sparse.diaarray`, `scipy.sparse.dokarray`, 
    `scipy.sparse.lilarray`, or `scipy.sparse.bsrarray`)'''
    __ducktype__ = (sparray, cscarray, cooarray, csrarray, diaarray, dokarray, lilarray, bsrarray)
    
    
class sparsematrix(Duck, Generic[*Ts]): 
    '''sparse type (e.g.  
    `scipy.sparse.spmatrix`, `scipy.sparse.cscmatrix`, `scipy.sparse.coomatrix`, 
    `scipy.sparse.csrmatrix`, `scipy.sparse.diamatrix`, `scipy.sparse.dokmatrix`, 
    `scipy.sparse.lilmatrix`, or `scipy.sparse.bsrmatrix`)'''
    __ducktype__ = (spmatrix, cscmatrix, coomatrix, csrmatrix, diamatrix, dokmatrix, lilmatrix, bsrmatrix)


# %% ../nbs/40_duck.ipynb 110
class sparse(Duck, Generic[*Ts]): 
    '''sparse type (e.g. `sparsearray` or `sparsematrix`)'''
    __ducktype__ = (sparray, sparsematrix)
    
class array(Duck, Generic[*Ts]): 
    '''array type (e.g. `np.array`, `np.recarray`, `sp.sparray`, `itertype`, or `list`)'''
    __ducktype__ = (nparray, recarray, sparray, itertype, list)
    
class matrix(Duck, Generic[*Ts]): 
    '''matrix type(e.g. `np.matrix`, `sp.matrix`, `itertype`, or `list`)'''
    __ducktype__ = (npmatrix, spmatrix, itertype, list)

# %% ../nbs/40_duck.ipynb 111
class sparseq(sparse[*Ts], Generic[*Ts]): 
    '''Optional sparse type (e.g. `sparsearray` or `sparsematrix`)'''
    __species__ = Species.OPT
    
class arrayq(array[*Ts], Generic[*Ts]): 
    '''Optional array type (e.g. `np.array`, `np.recarray`, `sp.sparray`, `itertype`, or `list`)'''
    __species__ = Species.OPT
    
class matrixq(matrix[*Ts], Generic[*Ts]): 
    '''Optional matrix type(e.g. `np.matrix`, `sp.matrix`, `itertype`, or `list`)'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 114
class cv2vidcap(Duck): 
    '''`cv2.VideoCapture`''';
    __ducktype__ = (eggs.cv_vidcap, )

class pilimage(Duck): 
    '''`PIL.Image.Image`''';
    __ducktype__ = (eggs.pil_image, )    

# %% ../nbs/40_duck.ipynb 116
class vidcap(Duck): 
    '''`cv2.VideoCapture`''';
    __ducktype__ = (eggs.cv_vidcap, )
    
class image(Duck): 
    '''`PIL.Image.Image`''';
    __ducktype__ = (eggs.pil_image, )

# %% ../nbs/40_duck.ipynb 119
class groupkey(Duck, Generic[*Ts]): 
    '''groupby key (e.g. `str`, `tuple`, or `numstr`)'''
    __ducktype__ = (str, tuple, numstr)
    

# %% ../nbs/40_duck.ipynb 121
class pddelegate(Duck):
    '''`pandas.core.accessor.PandasDelegate`''';
    __ducktype__ = (object, eggs.pd_delegate, )
    
class pdcataccessor(Duck):
    '''`pandas.core.arrays.categorical.CategoricalAccessor`''';
    __ducktype__ = (object, eggs.pd_cataccessor, )

# %% ../nbs/40_duck.ipynb 123
class pdindex(Duck, Generic[*Ts]):
    '''`pandas.Index`''';
    __ducktype__ = (eggs.pd_index, )
    
class pdcatindex(Duck, Generic[*Ts]):
    '''`pandas.CategoricalIndex`''';
    __ducktype__ = (eggs.pd_catindex, )

# %% ../nbs/40_duck.ipynb 126
class pdseries(Duck, Generic[*Ts]):
    '''`pandas.Series`''';
    __ducktype__ = (eggs.pd_series, )

# %% ../nbs/40_duck.ipynb 128
class boolindex(Duck, Generic[*Ts]):
    '''boolean index'''
    __ducktype__ = (list, pdindex, nparray, bools, )
    __expected__ = dict(dtype=bool01)
    
class catindex(Duck, Generic[*Ts]):
    '''categorical index'''
    __ducktype__ = (pdcatindex, )

# %% ../nbs/40_duck.ipynb 129
class boolindexq(boolindex[*Ts], Generic[*Ts]): 
    '''Optional[booleanindex]'''
    __species__ = Species.OPT
    
class catindexq(catindex[*Ts], Generic[*Ts]): 
    '''Optional[catindex]'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 131
class indextype(Duck): 
    '''index types(e.g. `pd.Index`, `pd.CategoricalIndex`, `np.ndarray`, or `boolindex`)'''
    __ducktype__ = (pdindex, pdcatindex, boolindex, nparray)
    
    
class indexlike(Duck): 
    '''index-like objects (e.g. `list`, `tuple`,`bools`, `nums`, 
    `itertype`, `pd.Index`, `pd.CategoricalIndex`, `boolindex`, or `np.array`)'''
    __ducktype__ = (list, tuple, bools, nums, itertype, pdindex, pdcatindex, boolindex, nparray)

# %% ../nbs/40_duck.ipynb 133
class seriestype(Duck, Generic[*Ts]):
    '''series type (e.g. `pd.Series`, `np.array`, `np.recarray`, `list`, or `indexlike`)'''
    __ducktype__ = (pdseries, nparray, recarray, list, indexlike)
    

class serieslike(Duck, Generic[*Ts]):
    '''series-like type'''
    __ducktype__ = (pdseries, nparray, recarray, list, indexlike)

# %% ../nbs/40_duck.ipynb 135
class pddataframe(Duck, Generic[*Ts]):
    '''`pandas.DataFrame`''';
    __ducktype__ = (eggs.pd_dataframe, )

# %% ../nbs/40_duck.ipynb 137
class dataframe(Duck, Generic[*Ts]):
    '''`pandas.DataFrame`''';
    __ducktype__ = (eggs.pd_dataframe, )

# %% ../nbs/40_duck.ipynb 140
class pttype(Duck, Generic[*Ts]):
    '''`torch.dtype`'''
    __ducktype__ = (eggs.pt_type, )
    
class pttypeq(pttype, Generic[*Ts]):
    '''`Optional[torch.dtype]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 142
class memfmt(Duck): 
    '''`torch.memory_format`''';
    __ducktype__ = (eggs.pt_memoryformat, )

class presfmt(Duck): 
    '''`torch.preserve_format`''';
    __ducktype__ = (eggs.pt_preserveformat, )

# %% ../nbs/40_duck.ipynb 144
class ptsize(Duck, Generic[*Ts]):
    '''`torch.Size`'''
    __ducktype__ = (eggs.pt_size, iterable, tuple, )
    
class ptsizeq(ptsize, Generic[*Ts]):
    '''`Optional[torch.Size]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 146
class ptdevice(Duck, Generic[*Ts]):
    '''`torch.device`'''
    __ducktype__ = (eggs.pt_device, iterable, tuple, )

class ptdeviceq(ptdevice, Generic[*Ts]):
    '''`Optional[torch.device]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 148
class pttensor(Duck, Generic[*Ts]): 
    '''`torch.Tensor`''';
    __ducktype__ = (eggs.pt_tensor, )
    
class inttensor(Duck, Generic[*Ts]): 
    '''`torch.IntTensor`''';
    __ducktype__ = (eggs.pt_inttensor, )
    
class booltensor(Duck, Generic[*Ts]): 
    '''`torch.BoolTensor`''';
    __ducktype__ = (eggs.pt_booltensor, )
    
class floattensor(Duck, Generic[*Ts]): 
    '''`torch.FloatTensor`''';
    __ducktype__ = (eggs.pt_floattensor, )
    
class longtensor(Duck, Generic[*Ts]): 
    '''`torch.LongTensor`''';
    __ducktype__ = (eggs.pt_longtensor, )
    
class doubletensor(Duck, Generic[*Ts]): 
    '''`torch.DoubleTensor`''';
    __ducktype__ = (eggs.pt_doubletensor, )

# %% ../nbs/40_duck.ipynb 149
class pttensorq(pttensor, Generic[*Ts]): 
    '''`Optional[torch.Tensor]`''';
    __species__ = Species.OPT
    
class inttensorq(inttensor, Generic[*Ts]): 
    '''`Optional[torch.IntTensor]`''';
    __species__ = Species.OPT
    
class booltensorq(booltensor, Generic[*Ts]): 
    '''`Optional[torch.BoolTensor]`''';
    __species__ = Species.OPT
    
class floattensorq(floattensor, Generic[*Ts]): 
    '''`Optional[torch.FloatTensor]`''';
    __species__ = Species.OPT
    
class longtensorq(longtensor, Generic[*Ts]): 
    '''`Optional[torch.LongTensor]`''';
    __species__ = Species.OPT
    
class doubletensorq(doubletensor, Generic[*Ts]): 
    '''`Optional[torch.DoubleTensor]`''';
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 151
class nantensor(Duck, Generic[*Ts]): 
    '''tensor of `nan`s'''
    __ducktype__ = (pttensor, nans, )
    __expected__ = dict(dtype=nan)
    

class nantensorq(nantensor[*Ts], Generic[*Ts]): 
    '''Optional tensor of `nan`s'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 153
class tensor(Duck, Generic[*Ts]): 
    '''tensor type (e.g. `torch.tensor`, `torch.IntTensor`, `torch.BoolTensor`, or `torch.FloatTensor`)'''
    __ducktype__ = (pttensor, inttensor, booltensor, floattensor, longtensor, doubletensor, )
    
class tensorq(tensor, Generic[*Ts]): 
    '''`Optional[tensor]`'''
    __species__ = Species.OPT
    
class pttensorq(pttensor, Generic[*Ts]): 
    '''`Optional[pttensor]`'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 155
class ptmodule(Duck): 
    '''`torch.nn.Module`'''
    __ducktype__ = (eggs.pt_module, )

class plmodule(Duck): 
    '''`pytorch_lightning.LightningModule`'''
    __ducktype__ = (eggs.pl_module, )

# %% ../nbs/40_duck.ipynb 157
class nnmodule(Duck): 
    '''module type (e.g. `torch.nn.Module` or `pytorch_lightning.LightningModule`)'''
    __ducktype__ = (ptmodule, plmodule, )

# %% ../nbs/40_duck.ipynb 159
class ptdataset(Duck): 
    '''`torch.utils.data.Dataset`'''
    __ducktype__ = (eggs.pt_dataset, )

class pldatamodule(Duck): 
    '''`pytorch_lightning.LightningDataModule`'''
    __ducktype__ = (eggs.pl_datamodule, )

class ptdataloader(Duck): 
    '''`torch.utils.data.DataLoader`'''
    __ducktype__ = (eggs.pt_dataloader, )


# %% ../nbs/40_duck.ipynb 162
class neuralode(Duck): 
    '''torchdyn neural ODE'''
    __ducktype__ = (eggs.td_neuralode, )

class neuralsde(Duck): 
    '''torchdyn neural SDE'''
    __ducktype__ = (eggs.td_neuralsde, )

class neuraldynamics(Duck): 
    '''neuralode or neuralsde'''
    __ducktype__ = (neuralode, neuralsde, )


# %% ../nbs/40_duck.ipynb 163
class augmenter(Duck): 
    '''`torchdyn.nn.augmenter`''';
    __ducktype__ = (eggs.td_augmenter, )

# %% ../nbs/40_duck.ipynb 164
class odefunc(Duck): 
    '''`torchdyn.ODEFunc`'''
    __ducktype__ = (eggs.td_odefunc, )

class sdefunc(Duck): 
    '''`torchdyn.SDEFunc`'''
    __ducktype__ = (eggs.td_sdefunc, )

# %% ../nbs/40_duck.ipynb 166
class sdeito(Duck): 
    '''`torchsde.ito`'''
    __ducktype__ = (eggs.ts_sdeito, )

class brownianintervial(Duck): 
    '''`torchsde.BrownianInterval`'''
    __ducktype__ = (eggs.ts_brownianinterval, )


# %% ../nbs/40_duck.ipynb 169
class dtype(Duck, Generic[*Ts]):
    '''Type of data (e.g. `np.dtype` or `torch.dtype`)'''
    __ducktype__ = (type, eggs.np_type, eggs.pt_type, )
    
class dtypeq(dtype[*Ts]):
    '''Optional type of data (e.g. `np.dtype` or `torch.dtype`)'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 171
class device(Duck, Generic[*Ts]):
    '''`torch.device`'''
    __ducktype__ = (eggs.pt_device, str, )
    __dev__: ClassVar[str] = 'cpu'
    
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        d = cls.__dev__
        isdev = grds._isdev(d)
        cls.__expected__.update(__dev__=d)
        cls.__extrafns__.update(__dev__=isdev)
        return cls
    
class deviceq(device, Generic[*Ts]): 
    '''`Optional [torch.device]`'''
    __species__ = Species.OPT
    @classmethod
    def __generate__(cls):
        dev = getattr(cls, __DEV__, None)
        try: return eggs.pt_device.duck(dev)
        except: return dev or None

# %% ../nbs/40_duck.ipynb 175
class devcpu(device[Literal['cpu']]):
    '''`torch.device['cpu']`'''
    __dev__: ClassVar[str] = 'cpu'
    
class devmps(device[Literal['mps']]):
    '''`torch.device['mps']`'''
    __dev__: ClassVar[str] = 'mps'
    
class devcuda(device[Literal['cuda']]):
    '''`torch.device['mps']`'''
    __dev__: ClassVar[str] = 'cuda'

# %% ../nbs/40_duck.ipynb 177
class size(itertype[*Ts], Generic[*Ts]): 
    '''size type (e.g. `tuple`, `torch.Size`, `itertype`)'''
    __ducktype__ = (tuple, ptsize, itertype, )
    __expected__ = dict(dtype=int)
    
    
class sizeq(size[*Ts]): 
    '''Optional size type (e.g. `tuple`, `torch.Size`, `itertype`)'''
    __species__ = Species.OPT

# %% ../nbs/40_duck.ipynb 179
class datasource(Duck, Generic[*Ts]): 
    '''`numpy.DataSource`''';
    __ducktype__ = (eggs.np_datasource, )   

# %% ../nbs/40_duck.ipynb 181
class adata(Duck): 
    '''`anndata.AnnData`''';
    __ducktype__ = (eggs.ad_adata, )

class adatas(Duck, Generic[*Ts]): 
    '''`anndata.AnnData`''';
    __ducktype__ = (itertype, )
    __expected__ = dict(dtype=adata)

# %% ../nbs/40_duck.ipynb 183
class graphtype(Duck, Generic[*Ts]): 
    '''graph type (e.g. `BaseGraph`, `DataGraph`, `LandmarkGraph`, `kNNGraph`, `TraditionalGraph`, 
    `MNNGraph`, `kNNLandmarkGraph`, `TraditionalLandmarkGraph`, or `MNNLandmarkGraph`)'''
    __ducktype__ = (
        eggs.gt_bgraph, eggs.gt_dgraph, eggs.gt_lgraph, 
        eggs.gt_kgraph, eggs.gt_tgraph, eggs.gt_mgraph, 
        eggs.gt_klgraph, eggs.gt_tlgraph, eggs.gt_mlgraph
    )

# %% ../nbs/40_duck.ipynb 185
class datatype(Duck, Generic[*Ts]):
    '''data type (e.g.  `np.array`, `np.matrix`, `sp.array`, `sp.matrix`,  `np.recarray`, or `anndata`)'''
    __ducktype__ = (array, matrix, adata, )


# %% ../nbs/40_duck.ipynb 187
class nnum(nums, nlen[*Ts]):
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        cls.__expected__.update(dtype=num)
        return cls

class nint(ints, nlen[*Ts]):
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        cls.__expected__.update(dtype=int)
        return cls
    
class nfloat(floats, nlen[*Ts]):
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        cls.__expected__.update(dtype=float)
        return cls

# %% ../nbs/40_duck.ipynb 189
class int2(nint[int, int], len2): 
    '''A ducktype for an iterable of ints with length 2'''

class int3(nint[int, int, int], len3): 
    '''A ducktype for an iterable of ints with length 3'''


class int4(nint[int, int, int, int], len4): 
    '''A ducktype for an iterable of ints with length 4'''


# %% ../nbs/40_duck.ipynb 193
class shaped(Duck, Generic[*Ts]): 
    '''shaped `datatype`'''
    __ducktype__ = (datatype, indextype, seriestype, dataframe, tensor, )
    __required__ = (SHAPE, )

# %% ../nbs/40_duck.ipynb 195
class dimmed(Duck, Generic[*Ts]):
    '''`np.ndarray` with shape `(i, ...)`'''
    __ducktype__ = (list, nparray, list, itertype, )
    __required__ = (NDIM, )

class dim1(dimmed, Generic[*Ts]):
    '''`np.ndarray` with shape `(i, )`'''
    __expected__ = dict(ndim=1)
    

class dim2(dimmed, Generic[*Ts]):
    '''`np.ndarray` with shape `(i, j, )`'''
    __expected__ = dict(ndim=2)
    

class dim3(dimmed, Generic[*Ts]):
    '''`np.ndarray` with shape `(i, j, k, )`'''
    __expected__ = dict(ndim=3)

class dim4(dimmed, Generic[*Ts]):
    '''`np.ndarray` with shape `(i, j, k, l, )`'''
    __expected__ = dict(ndim=4)

# %% ../nbs/40_duck.ipynb 197
class genset(Duck[set], Generic[*Ts]):
    '''A type alias for a generic set type.''';
    __ducktype__ = (set, )
    
class setstr(genset[str]):
    '''A type alias for a set of strings.''';
    __expected__ = dict(dtype=str)
    
class setnum(genset[num]):
    '''A type alias for a set of numbers.''';
    __expected__ = dict(dtype=num)

# %% ../nbs/40_duck.ipynb 199
class kvdict(Duck[dict[T, O]], Generic[T, O]):
    '''A type alias for a generic set type.''';
    __ducktype__ = (dict, )
    __required__ = (KEYS, VALUES, )
    
    __k__: ClassVar[Type[T]] = str
    __v__: ClassVar[Type[T]] = notnone
    __kvtypes__: ClassVar[tuple[T, O]] = (str, notnone)
    
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        
        t = getattr(cls, __KVTYPES__, (None, None))
        k = getattr(cls, __K__, None)
        v = getattr(cls, __V__, None)
        if t == (None, None): t = (k, v)
        if k is None: k = t[0]
        if v is None: v = t[1]
        
        if not hasattr(cls, __KVTYPES__): setattr(cls, __KVTYPES__, t)
        if not hasattr(cls, __K__): setattr(cls, __K__, k)
        if not hasattr(cls, __V__): setattr(cls, __V__, v)
        istmap = grds._iskvdict(cls)
        cls.__expected__.update(__k__=k, __v__=v, __kvtypes__=t)
        cls.__extrafns__.update(__k__=istmap, __v__=istmap, __kvtypes__=istmap)
        return cls
    

# %% ../nbs/40_duck.ipynb 201
class pttndict(kvdict[str, pattern]): 
    '''A type alias for a dictionary of named regex patterns dict[str, re.Pattern]''';
    __ducktype__ = (dict, )
    __k__: ClassVar[Type[T]] = str
    __v__: ClassVar[Type[T]] = pattern
    __kvtypes__: ClassVar[tuple[T, O]] = (str, pattern)

# %% ../nbs/40_duck.ipynb 203
class annreturn(Duck[Callable[P, T]]): 
    '''A type alias for an Annotated Return of a Callable.'''
    __ducktype__ = (Callable, )
    __retannot__: ClassVar[T] = bool01
    
    @classmethod
    def __guard__(cls, obj: Any) -> bool:
        return super().__instancecheck__(obj) and getretann(obj) in cls.__ducktype__
    
    
    @classmethod
    def __metahook__(cls, mcls, name, bases, namespace, **kwargs):
        super().__metahook__(mcls, name, bases, namespace, **kwargs)
        
        t = getattr(cls, __RETANNOT__, bool)
        if not hasattr(cls, __RETANNOT__): 
            setattr(cls, __RETANNOT__, t)
            
        def isretann(obj, val) -> TypeGuard[T]:
            return getretann(obj) in (cls.__retannot__, *cls.__ducktype__, )
        
        cls.__expected__.update(__retannot__=t)
        cls.__extrafns__.update(__retannot__=isretann)
        return cls

# %% ../nbs/40_duck.ipynb 205
class slicelike(Duck):
    '''A type alias for a slice or the integers corresponding to the
    `(start, stop, step)` of a slice i.e. `slice | tuple[intq, int, intq]`
    
    Notes
    -----
    slice : SliceFormats
        The default representations of a python slice, i.e. 
        `(start: int, stop: int, step: int)`
        
    coord : SliceFormats
        The coordinate repesentation of a python slice i.e. 
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    __nones_ok : bool
        A sometimes optional parameter for slice utility functions.
        If `True`, the result is not corrected to prevent None values.
        i.e. `slice(0, 10, None)` would become `slice(0, 10, 1)`
        
                
    Definitions
    -----------
    :slice: `slice`
        The standard representation for a python slice, e.g.
        `(start: int, stop: int, step: int)` or `slice(0, 10, 2)`
    
    
    :svals: `tuple[int | None, int, int | None]`
        The integer representation for a python slice, e.g.
        `(start: int | None, stop: int, step: int | None)` or `slice(0, 10, None)`
        
    :slices: `tuple[slice | svals, ...] `
        An iterable of like representation for a python slice, e.g.
        `slice(0, 10, 2)`, `tuple(0, 10, 2)`, `tuple(0, 10, None)`, etc
    
    :coord: `tuple[int, ...]`
        The coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    :coords: `tuple[coord, ...]`
        An iterable of like coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
    
    Examples
    -------- 
    >>> slices = (0, 5), (2, 10) # slice format: (x0, x1), (y0, y1)
    ... tocoordformat(slices) # convert to coordinate format
    ((0, 2), (5, 10)) 

    >>> coords = (0, 2), (5, 10) # coord format: (x0, y0), (x1, y1)
    ... tosliceformat(coords) # convert to slice format
    ((0, 5), (2, 10))
    
    See Also
    --------
    asto.slcs.tocoordformat: convert slices in slice format to coordinate format
    asto.slcs.tosliceformat: convert slices in coordinate format to slice format
    '''
    __ducktype__ = (slice, int3)
    
    
class slicespec(Duck):
    '''A type alias for a slice or one of two formats to specify a slice.
    
    Notes
    -----
    slice : SliceFormats
        The default representations of a python slice, i.e. 
        `(start: int, stop: int, step: int)`
        
    coord : SliceFormats
        The coordinate repesentation of a python slice i.e. 
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    __nones_ok : bool
        A sometimes optional parameter for slice utility functions.
        If `True`, the result is not corrected to prevent None values.
        i.e. `slice(0, 10, None)` would become `slice(0, 10, 1)`
        
                
    Definitions
    -----------
    :slice: `slice`
        The standard representation for a python slice, e.g.
        `(start: int, stop: int, step: int)` or `slice(0, 10, 2)`
    
    
    :svals: `tuple[int | None, int, int | None]`
        The integer representation for a python slice, e.g.
        `(start: int | None, stop: int, step: int | None)` or `slice(0, 10, None)`
        
    :slices: `tuple[slice | svals, ...] `
        An iterable of like representation for a python slice, e.g.
        `slice(0, 10, 2)`, `tuple(0, 10, 2)`, `tuple(0, 10, None)`, etc
    
    :coord: `tuple[int, ...]`
        The coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    :coords: `tuple[coord, ...]`
        An iterable of like coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
    
    Examples
    -------- 
    >>> slices = (0, 5), (2, 10) # slice format: (x0, x1), (y0, y1)
    ... tocoordformat(slices) # convert to coordinate format
    ((0, 2), (5, 10)) 

    >>> coords = (0, 2), (5, 10) # coord format: (x0, y0), (x1, y1)
    ... tosliceformat(coords) # convert to slice format
    ((0, 5), (2, 10))
    
    See Also
    --------
    asto.slcs.tocoordformat: convert slices in slice format to coordinate format
    asto.slcs.tosliceformat: convert slices in coordinate format to slice format
    '''
    __ducktype__ = (slicelike, tuple, tuple[int, ...])
    
    
class slicespecs(itertype[slicespec]):
    '''A type alias for a list of slices, the integers corresponding to the
    `(start, stop, step)` of a slice or a slicespec.
    
    Notes
    -----
    slice : SliceFormats
        The default representations of a python slice, i.e. 
        `(start: int, stop: int, step: int)`
        
    coord : SliceFormats
        The coordinate repesentation of a python slice i.e. 
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    __nones_ok : bool
        A sometimes optional parameter for slice utility functions.
        If `True`, the result is not corrected to prevent None values.
        i.e. `slice(0, 10, None)` would become `slice(0, 10, 1)`
        
                
    Definitions
    -----------
    :slice: `slice`
        The standard representation for a python slice, e.g.
        `(start: int, stop: int, step: int)` or `slice(0, 10, 2)`
    
    
    :svals: `tuple[int | None, int, int | None]`
        The integer representation for a python slice, e.g.
        `(start: int | None, stop: int, step: int | None)` or `slice(0, 10, None)`
        
    :slices: `tuple[slice | svals, ...] `
        An iterable of like representation for a python slice, e.g.
        `slice(0, 10, 2)`, `tuple(0, 10, 2)`, `tuple(0, 10, None)`, etc
    
    :coord: `tuple[int, ...]`
        The coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
        
    :coords: `tuple[coord, ...]`
        An iterable of like coordinate representation for a python slice, e.g.
        `(x0, y0, ...), (x1, y1, ...), ...`
    
    Examples
    -------- 
    >>> slices = (0, 5), (2, 10) # slice format: (x0, x1), (y0, y1)
    ... tocoordformat(slices) # convert to coordinate format
    ((0, 2), (5, 10)) 

    >>> coords = (0, 2), (5, 10) # coord format: (x0, y0), (x1, y1)
    ... tosliceformat(coords) # convert to slice format
    ((0, 5), (2, 10))
    
    See Also
    --------
    asto.slcs.tocoordformat: convert slices in slice format to coordinate format
    asto.slcs.tosliceformat: convert slices in coordinate format to slice format
    ''';
    __ducktype__ = (slicespec, )

# %% ../nbs/40_duck.ipynb 208
class richtree(Duck):
    '''`rich.tree.Tree`'''
    __ducktype__ = (eggs.r_richtree, )
    
class richtext(Duck):
    '''`rich.text.Text`'''
    __ducktype__ = (eggs.r_richtext, )
    
class richcons(Duck):
    '''`rich.console.Console`'''
    __ducktype__ = (eggs.r_richcons, )
    
class richprog(Duck):
    '''`rich.progress.Progress`'''
    __ducktype__ = (eggs.r_richprog, )
    
class richtask(Duck):
    '''`rich.progress.Task`'''
    __ducktype__ = (eggs.r_richtask, )

# %% ../nbs/40_duck.ipynb 210
class tqdmauto(Duck):
    '''`tqdm.auto.tqdm`'''
    __ducktype__ = (eggs.tq_as, )

# %% ../nbs/40_duck.ipynb 212
class typerapp(Duck):
    '''`typer.Typer`'''
    __ducktype__ = (eggs.t_typer, )
    
