diff --git a/flox/xrutils.py b/flox/xrutils.py index 37e18567..2addf35f 100644 --- a/flox/xrutils.py +++ b/flox/xrutils.py @@ -4,6 +4,7 @@ import datetime import importlib from collections.abc import Iterable +from types import ModuleType from typing import Any import numpy as np @@ -45,13 +46,20 @@ def module_available(module: str, minversion: str | None = None) -> bool: except ImportError: cftime = None +cubed: ModuleType | None +try: + import cubed # type: ignore[no-redef] +except ImportError: + cubed = None +dask: ModuleType | None try: import dask.array - dask_array_type = dask.array.Array + dask_array_type = dask.array.Array # type: ignore[union-attr] except ImportError: - dask_array_type = () # type: ignore[assignment, misc] + dask = None + dask_array_type = () def asarray(data, xp=np): @@ -79,13 +87,9 @@ def is_chunked_array(x) -> bool: def is_dask_collection(x): - try: - import dask - - return dask.is_dask_collection(x) - - except ImportError: + if dask is None: return False + return dask.is_dask_collection(x) def is_duck_dask_array(x): @@ -93,12 +97,9 @@ def is_duck_dask_array(x): def is_duck_cubed_array(x): - try: - import cubed - - return is_duck_array(x) and isinstance(x, cubed.Array) - except ImportError: + if cubed is None: return False + return is_duck_array(x) and isinstance(x, cubed.Array) class ReprObject: @@ -140,7 +141,7 @@ def is_scalar(value: Any, include_0d: bool = True) -> bool: or isinstance(value, str | bytes | dict) or not ( isinstance(value, (Iterable,) + NON_NUMPY_SUPPORTED_ARRAY_TYPES) - or hasattr(value, "__array_function__") + or hasattr(value, "__array_function__") # type: ignore[unreachable] ) ) @@ -182,13 +183,13 @@ def isnull(data: Any): else: # at this point, array should have dtype=object if isinstance(data, (np.ndarray, dask_array_type)): # noqa - return pd.isnull(data) # type: ignore[arg-type] + return pd.isnull(data) else: # Not reachable yet, but intended for use with other duck array # types. For full consistency with pandas, we should accept None as # a null value as well as NaN, but it isn't clear how to do this # with duck typing. - return data != data + return data != data # type: ignore[unreachable] def datetime_to_numeric(array, offset=None, datetime_unit=None, dtype=float):