from distutils.version import LooseVersion from importlib import import_module import numpy as np from .utils import is_duck_array integer_types = (int, np.integer) class DuckArrayModule: """ Solely for internal isinstance and version checks. Motivated by having to only import pint when required (as pint currently imports xarray) https://github.com/pydata/xarray/pull/5561#discussion_r664815718 """ def __init__(self, mod): try: duck_array_module = import_module(mod) duck_array_version = LooseVersion(duck_array_module.__version__) if mod == "dask": duck_array_type = (import_module("dask.array").Array,) elif mod == "pint": duck_array_type = (duck_array_module.Quantity,) elif mod == "cupy": duck_array_type = (duck_array_module.ndarray,) elif mod == "sparse": duck_array_type = (duck_array_module.SparseArray,) else: raise NotImplementedError except ImportError: # pragma: no cover duck_array_module = None duck_array_version = LooseVersion("0.0.0") duck_array_type = () self.module = duck_array_module self.version = duck_array_version self.type = duck_array_type self.available = duck_array_module is not None def is_duck_dask_array(x): if DuckArrayModule("dask").available: from dask.base import is_dask_collection return is_duck_array(x) and is_dask_collection(x) else: return False dsk = DuckArrayModule("dask") dask_version = dsk.version dask_array_type = dsk.type sp = DuckArrayModule("sparse") sparse_array_type = sp.type sparse_version = sp.version cupy_array_type = DuckArrayModule("cupy").type