# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_atyp.ipynb.

# %% auto 0
__all__ = ['T', 'O', 'G', 'P', 'Types', 'Guard', 'IterT', 'IterStr', 'IterFunc', 'IterType', 'GuardIter', 'GuardIterT',
           'GuardIterType', 'NanGuard', 'GuardLike', 'AttrGuards', 'OriginTypes', 'OriginGuard', 'HasIterElements',
           'HasHash', 'IsNotSpecial', 'Namespace', 'ImportedAsset']

# %% ../nbs/03_atyp.ipynb 6
import math

# %% ../nbs/03_atyp.ipynb 8
from types import (ModuleType, FunctionType, SimpleNamespace, BuiltinFunctionType, BuiltinMethodType)

import typing
from typing import (Dict, Type, Tuple, Union, TypeVar, TypeAlias, TypeGuard, ParamSpec, Callable, Iterable, )

# %% ../nbs/03_atyp.ipynb 10
#| export


# %% ../nbs/03_atyp.ipynb 12
from nlit import __HASH__

# %% ../nbs/03_atyp.ipynb 14
try: from ptyp.duck import NonStrBytesIterable, Hashable, NotSpecial
except: ...

# %% ../nbs/03_atyp.ipynb 17
T = TypeVar('T')
'''Generic type variable that can represent any type.''';

O = TypeVar('O')
'''Generic type variable that can represent any object.''';

G = TypeVar('G')
'''Generic type variable that can represent any Graph.''';

P = ParamSpec('P')
'''Parameter specification type variable, capturing the type of function parameters.''';

Types: TypeAlias = Tuple[Type, ...]
'''TypeAlias for a tuple of types, representing a collection of type objects.''';

Guard: TypeAlias = TypeGuard[T]
'''TypeAlias for TypeGuard that specifically guards an object of type T.''';

IterT: TypeAlias = Iterable[T]
'''TypeAlias for any iterable containing elements of type T.''';

IterStr: TypeAlias = Iterable[str]
'''TypeAlias for an iterable of strings.''';

IterFunc: TypeAlias = Iterable[FunctionType]
'''TypeAlias for an iterable of function objects.''';

IterType: TypeAlias = Iterable[Type]
'''TypeAlias for an iterable of types.''';

GuardIter: TypeAlias = TypeGuard[Iterable]
'''TypeAlias for TypeGuard specifically guarding any iterable object.''';

GuardIterT: TypeAlias = TypeGuard[Iterable[T]]
'''TypeAlias for TypeGuard, guarding iterables containing elements of type T.''';

GuardIterType: TypeAlias = TypeGuard[Iterable[Type]]
'''TypeAlias for TypeGuard, guarding iterables containing elements of types.''';

NanGuard: TypeAlias = TypeGuard[math.nan]
'''TypeAlias for TypeGuard specifically guarding the math.nan object.''';

GuardLike: TypeAlias = Callable[[O], TypeGuard[T]]
'''TypeAlias for a callable that takes an object of type O and returns a TypeGuard for type T.''';

AttrGuards: TypeAlias = Dict[str, Callable[[O, T], TypeGuard[T]]]
'''TypeAlias for a dictionary mapping attribute names to guard functions, 
which take an object of type T and an arbitrary value and return a boolean.''';

# %% ../nbs/03_atyp.ipynb 19
OriginTypes: TypeAlias = Union[
    (
        otypes := [
            otype for attr in dir(typing) 
            if (
                typing.get_origin(otype := getattr(typing, attr)) 
                and hasattr(otype, __HASH__)) and 
                not (
                    isinstance(otype, typing._SpecialForm) or otype in (typing.Generic, typing.Protocol)
                )
        ]
    )[0],
    *otypes[1:]
]
'''A union of types from the `typing` module that:
    - have origins (i.e., they are not base types), 
    - are hashable, and 
    - are not special forms or the `Generic` and `Protocol` types. 

This includes types like `List[int]`, `Dict[str, int]`, etc., but excludes basic types like 
`int`, `str`, and `typing` specific constructs like `Generic` or `Protocol`.'''

OriginGuard: TypeAlias = TypeGuard[OriginTypes]
'''TypeGuard for `OriginTypes`. It is used to narrow down a variable to one of the types that have origins in the `typing` module,
are hashable, and not special forms or `Generic` or `Protocol` types. Useful in type checking scenarios to confirm the type of an object
against these specific origin types from the `typing` module.''';

# %% ../nbs/03_atyp.ipynb 21
HasIterElements: TypeAlias = TypeGuard['NonStrBytesIterable']
'''TypeAlias for TypeGuard specifically guarding an iterable object that is not a string or bytes. 
This is useful to find objects which can be recursed into and each element may not be uniformly of the same type.
''';

HasHash: TypeAlias = TypeGuard['Hashable']
'''TypeAlias for TypeGuard specifically guarding a hashable object.''';

IsNotSpecial: TypeAlias = TypeGuard['NotSpecial']
'''TypeAlias for TypeGuard specifically guarding an object that is not a special form.''';

# %% ../nbs/03_atyp.ipynb 23
Namespace: TypeAlias = Union[Dict[str, T], SimpleNamespace]
'''TypeAlias for a union of a dictionary and a `SimpleNamespace` object.''';

ImportedAsset: TypeAlias = Union[T, Type, FunctionType, BuiltinFunctionType, BuiltinMethodType, ModuleType]
'''TypeAlias for a union of a function, a builtin function, a builtin method, and a module object.''';
