# isort:skip_file
from .version import __version__

# first-class class
from .qdict import qDict
from .qtimer import Timer
from .data.qdatalist import qDataList, qList
from .torch.qdataset import qData, qDictDataloader, qDictDataset, qLmdbDataset
from .torch.qoptim import CompositeOptim, CompositeScheduler
from .torch.nn.donothing import Donothing
from .qimport import LazyImportErrorProxy, LazyImport

# first-class module
from .torch import nn
from .torch import qdist
from .torch import qcheckpoint, qscatter, qsparse
from .torch import qcontextprovider
from . import data, plugins


# first-class funciton
from .qimport import import_common
from .config.qssert import batch_assert_type
from .config.yaml import dump_yaml, load_yaml
from .config.qpickle import load_pickle, save_pickle
from .config.qjson import load_json, save_json
from .config.qsyspath import find_root, update_sys
from .torch.qcontextprovider import qContextProvider


# training
from .torch.qcheckpoint import recover, save_ckp
from .torch.qgpu import parse_device
from .torch.qfreeze import freeze_rand, freeze_module, unfreeze_module
from .torch.qsplit import random_split_train_valid, random_split_train_valid_test, get_data_splits
from .torch.nn.donothing import donothing
from .torch.qscatter import scatter, softmax

# type & check
from .utils.qtyping import Bool, Float,Long, Float16, Float32, Float64, Int32, Int64, Float32Array, Float64Array, BoolArray, Int32Array, Int64Array # fmt: skip
from .utils.qtypecheck import ensure_scala, ensure_numpy, str2number, is_number, is_inf
from .utils.check import check_values_allowed, is_alias_exists

# attr
from .utils.attr import hasattr_safe, getmultiattr, is_override


# plugins
def __getattr__(name):
    if name == "plugins":
        import importlib

        return importlib.import_module(".plugins", __name__)
    raise AttributeError(f"module {__name__} has no attribute {name}")
