TIFNJK_E41221588/venv/Lib/site-packages/altair/datasets/_exceptions.py

108 lines
3.7 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Sequence
from altair.datasets._reader import _Backend
from altair.datasets._typing import Metadata
class AltairDatasetsError(Exception):
@classmethod
def from_url(cls, meta: Metadata, /) -> AltairDatasetsError:
if meta["suffix"] == ".parquet":
msg = (
f"{_failed_url(meta)}"
f"{meta['suffix']!r} datasets require `vegafusion`.\n"
"See upstream issue for details: https://github.com/vega/vega/issues/3961"
)
else:
msg = (
f"{cls.from_url.__qualname__}() called for "
f"unimplemented extension: {meta['suffix']}\n\n{meta!r}"
)
raise NotImplementedError(msg)
return cls(msg)
@classmethod
def from_tabular(cls, meta: Metadata, backend_name: str, /) -> AltairDatasetsError:
if meta["is_image"]:
reason = "Image data is non-tabular."
return cls(f"{_failed_tabular(meta)}{reason}{_suggest_url(meta)}")
elif not meta["is_tabular"] or meta["suffix"] in {".arrow", ".parquet"}:
if meta["suffix"] in {".arrow", ".parquet"}:
install: tuple[str, ...] = "pyarrow", "polars"
what = f"{meta['suffix']!r}"
else:
install = ("polars",)
if meta["is_spatial"]:
what = "Geospatial data"
elif meta["is_json"]:
what = "Non-tabular json"
else:
what = f"{meta['file_name']!r}"
reason = _why(what, backend_name)
return cls(f"{_failed_tabular(meta)}{reason}{_suggest_url(meta, *install)}")
else:
return cls(_implementation_not_found(meta))
@classmethod
def from_priority(cls, priority: Sequence[_Backend], /) -> AltairDatasetsError:
msg = f"Found no supported backend, searched:\n{priority!r}"
return cls(msg)
def module_not_found(
backend_name: str, reqs: Sequence[str], missing: str
) -> ModuleNotFoundError:
if len(reqs) == 1:
depends = f"{reqs[0]!r} package"
else:
depends = ", ".join(f"{req!r}" for req in reqs) + " packages"
msg = (
f"Backend {backend_name!r} requires the {depends}, but {missing!r} could not be found.\n"
f"This can be installed with pip using:\n"
f" pip install {missing}\n"
f"Or with conda using:\n"
f" conda install -c conda-forge {missing}"
)
return ModuleNotFoundError(msg, name=missing)
def _failed_url(meta: Metadata, /) -> str:
return f"Unable to load {meta['file_name']!r} via url.\n"
def _failed_tabular(meta: Metadata, /) -> str:
return f"Unable to load {meta['file_name']!r} as tabular data.\n"
def _why(what: str, backend_name: str, /) -> str:
return f"{what} is not supported natively by {backend_name!r}."
def _suggest_url(meta: Metadata, *install_other: str) -> str:
other = ""
if install_other:
others = " or ".join(f"`{other}`" for other in install_other)
other = f" installing {others}, or use"
return (
f"\n\nInstead, try{other}:\n"
" from altair.datasets import data\n"
f" data.{meta['dataset_name']}.url"
)
def _implementation_not_found(meta: Metadata, /) -> str:
"""Search finished without finding a *declared* incompatibility."""
INDENT = " " * 4
record = f",\n{INDENT}".join(
f"{k}={v!r}"
for k, v in meta.items()
if not (k.startswith(("is_", "sha", "bytes", "has_")))
or (v is True and k.startswith("is_"))
)
return f"Found no implementation that supports:\n{INDENT}{record}"