# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/05_attr.ipynb.

# %% auto 0
__all__ = []

# %% ../nbs/05_attr.ipynb 6
from functools import wraps

# %% ../nbs/05_attr.ipynb 8
from typing import Any, overload

# %% ../nbs/05_attr.ipynb 10
try: import numpy as np
except: ...

#| export
try: import torch
except: ...

# %% ../nbs/05_attr.ipynb 12
from nchr import U1, DOT
from nlit import SHAPE, NDIM, SEEDED
from nlit import IS_BUILT, IS_AVAILABLE
from quac import ints, tupleq
from atup import fillnone
from astr import insattr, astr

# %% ../nbs/05_attr.ipynb 14
from .cons import WRAPS_ASSIGN_ANNDOCS

# %% ../nbs/05_attr.ipynb 17
class _shape(astr):
    '''getattr(obj, 'shape', ()) or obj''';
    attr = SHAPE
    guard = ints
    default = ()
    retself = True
    
class _avail(astr):
    attr = IS_AVAILABLE
    default = lambda : False
    retself = False
    
class _built(astr):
    attr = IS_BUILT
    default = lambda : False
    retself = False
    
class _ndim(astr):
    attr = NDIM
    default = 0
    retself = False
    
class _seeded(astr):
    attr = f'{U1}{SEEDED}'
    default = False
    retself = False

# %% ../nbs/05_attr.ipynb 19
def gets(o: object, *attrs, defaults: tupleq = None) -> tuple:
    '''Retrieves multiple attributes from `o`, providing `defaults` for missing attributes.
    
    Parameters
    ----------
    o : object
        The object to retrieve attributes from.
    
    *attrs : str
        The names of the attributes to retrieve.
        
    defaults : tuple, optional
        Default values for each attribute, if not found.
        
    Returns
    -------
    tuple
        A tuple containing the values of the requested attributes or their defaults.
    '''
    defs = fillnone(defaults, len(attrs))
    return tuple(insattr(o, a, d) for a, d in zip(attrs, defs))

@wraps(gets, assigned=WRAPS_ASSIGN_ANNDOCS)
def getattrs(o: object, *attrs, defaults: tupleq = None) -> tuple:
    return gets(o, *attrs, defaults=defaults)

# %% ../nbs/05_attr.ipynb 21
class nested:
    def __init__(self, attr, *attrs, __default=None):
        names = attr.split(DOT) + list(attrs)
        def func(obj, defs = __default):
            for name in names:
                obj = getattr(obj, name, __default=defs)
            return obj
        
        self.func = func
        self.strs = names
        self.defs = __default
        self.repr = ', '.join(map(repr, self.strs))
        
    def __call__(self, obj, __default = None):
        return self.func(obj, __default or self.defs)

    def __repr__(self):
        f'{self.__class__.__qualname__}({self.repr})'

# %% ../nbs/05_attr.ipynb 23
#| export
