Skip to content

Commit

Permalink
test: Adds tests for missing dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
dangotbanned committed Nov 11, 2024
1 parent 9d88e1b commit 60d39f5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
14 changes: 13 additions & 1 deletion altair/datasets/_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,19 @@ def _import(self, name: str, /) -> Any:
if spec := find_spec(name):
return import_module(spec.name)
else:
msg = f"{type(self).__name__!r} requires missing dependency {name!r}."
reqs = _requirements(self._name) # type: ignore[call-overload]
if isinstance(reqs, tuple):
depends = ", ".join(f"{req!r}" for req in reqs) + " packages"
else:
depends = f"{reqs!r} package"

msg = (
f"Backend {self._name!r} requires the {depends}, but {name!r} could not be found.\n"
f"This can be installed with pip using:\n"
f" pip install {name}\n"
f"Or with conda using:\n"
f" conda install -c conda-forge {name}"
)
raise ModuleNotFoundError(msg, name=name)

def __repr__(self) -> str:
Expand Down
48 changes: 46 additions & 2 deletions tests/test_datasets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import re
import sys
from importlib.util import find_spec
from typing import TYPE_CHECKING

Expand All @@ -13,8 +14,12 @@
from tests import skip_requires_pyarrow

if TYPE_CHECKING:
from typing import Literal

from altair.datasets._readers import _Backend

CACHE_ENV_VAR: Literal["ALTAIR_DATASETS_DIR"] = "ALTAIR_DATASETS_DIR"


requires_pyarrow = skip_requires_pyarrow()

Expand Down Expand Up @@ -58,10 +63,49 @@ def test_loader_url(backend: _Backend) -> None:


@backends
def test_loader_call(backend: _Backend) -> None:
def test_loader_call(backend: _Backend, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv(CACHE_ENV_VAR, raising=False)

data = Loader.with_backend(backend)
data.cache_dir = "" # type: ignore[assignment]
frame = data("stocks", ".csv")
assert is_into_dataframe(frame)
nw_frame = nw.from_native(frame)
assert set(nw_frame.columns) == {"symbol", "date", "price"}


@backends
def test_missing_dependency_single(
backend: _Backend, monkeypatch: pytest.MonkeyPatch
) -> None:
if backend in {"polars[pyarrow]", "pandas[pyarrow]"}:
pytest.skip("Testing single dependency backends only")

monkeypatch.setitem(sys.modules, backend, None)

with pytest.raises(
ModuleNotFoundError,
match=re.compile(
rf"{backend}.+requires.+{backend}.+but.+{backend}.+not.+found.+pip install {backend}",
flags=re.DOTALL,
),
):
Loader.with_backend(backend)


@pytest.mark.parametrize("backend", ["polars[pyarrow]", "pandas[pyarrow]"])
@skip_requires_pyarrow
def test_missing_dependency_multi(
backend: _Backend, monkeypatch: pytest.MonkeyPatch
) -> None:
secondary = "pyarrow"
primary = backend.removesuffix(f"[{secondary}]")
monkeypatch.setitem(sys.modules, secondary, None)

with pytest.raises(
ModuleNotFoundError,
match=re.compile(
rf"{re.escape(backend)}.+requires.+'{primary}', '{secondary}'.+but.+{secondary}.+not.+found.+pip install {secondary}",
flags=re.DOTALL,
),
):
Loader.with_backend(backend)

0 comments on commit 60d39f5

Please sign in to comment.