diff --git a/xarray/namedarray/utils.py b/xarray/namedarray/utils.py index 3490a76aa8d..e4267637e17 100644 --- a/xarray/namedarray/utils.py +++ b/xarray/namedarray/utils.py @@ -60,6 +60,9 @@ def module_available(module: str, minversion: str | None = None) -> bool: if minversion is not None: version = importlib.metadata.version(module) + if version is None: + return False + return Version(version) >= Version(minversion) return True diff --git a/xarray/tests/test_utils.py b/xarray/tests/test_utils.py index 90fdcb7d561..5bc2240ac8d 100644 --- a/xarray/tests/test_utils.py +++ b/xarray/tests/test_utils.py @@ -2,6 +2,7 @@ from collections.abc import Hashable from types import EllipsisType +from unittest.mock import patch import numpy as np import pandas as pd @@ -15,6 +16,7 @@ infix_dims, iterate_nested, ) +from xarray.namedarray.utils import module_available from xarray.tests import assert_array_equal, requires_dask @@ -391,6 +393,23 @@ def f(): assert f() == 3 +# regression test +def test_module_available_with_none_version() -> None: + module_available.cache_clear() + + try: + with ( + patch("importlib.util.find_spec", return_value=object()), + patch("importlib.metadata.version", return_value=None), + ): + assert not module_available( + "package_with_missing_version", + minversion="1.0", + ) + finally: + module_available.cache_clear() + + def test_attempt_import() -> None: """Test optional dependency handling.""" np = attempt_import("numpy")