Skip to content

ENH: Throw informative error if missing optional dependency #9554

Closed
@scott-huberty

Description

@scott-huberty

This ticket proposes two separate but overlapping ideas.

1. When trying to write/read Zarr files, throw an informative error if the user does not have zarr installed

just as Xarray does for other optional dependencies like Matplotlib.

Reproducible Code

Assuming you only have the base Xarray deps installed:

import xarray as xr


da = xr.DataArray([1, 2, 3],
                  dims='x',
                  coords={'x': [10, 20, 30]}
                  )
da.plot() # Raises a more informative ImportError
da.to_zarr('./test.zarr') # Does not raise an informative ImportError

2. Create a utility function to handle optional dependency imports across the Xarray code base.

Doing git grep "raise ImportError" or git grep "raise ModuleNotFoundError" reveals that currently there is a piecemeal approach to handling optional dependencies. It would probably be helpful to have a dedicated function to handle soft dependencies across the code base, and I would be happy to add this If I am going to be adding a PR for point 1 anyways.

Describe the solution you'd like

I work on an applied neuroscience package named MNE-Python, where we have a lot of optional dependencies that are only needed for specific MNE functionalities. So borrowing from MNE, I think something like this would be nice:

# xarray.util.check.py

import importlib


def _soft_import(name, reason, strict=True):
    """Import optional dependencies, providing informative errors on failure."""
    _INSTALL_MAPPING = dict(nc_time_axis="nc-time-axis")
    package_name = _INSTALL_MAPPING.get(name, name)
    try:
        return importlib.import_module(name)
    except (ImportError, ModuleNotFoundError):
        if strict:
            raise ImportError(
                f"for {reason}, the {package_name} package is required. "
                f"Please install it via pip or conda."
            )
        else:
            return None

Then, for example, here, we can instead do:

zarr = _soft_import("zarr", reason="writing zarr files")

And if we don't have zarr installed we'd get:

ImportError: for writing zarr files, the zarr package is required. Please install it via pip or conda.

Describe alternatives you've considered

Open to any ideas 🙂

Additional context

What do folks think about this idea? Is a PR welcome?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions