From 52ca2d8be359dba74cbe25d119befc10d09e9fda Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:04:46 +0000 Subject: [PATCH 1/4] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/biomejs/pre-commit: v2.4.4 → v2.4.6](https://github.com/biomejs/pre-commit/compare/v2.4.4...v2.4.6) - [github.com/astral-sh/ruff-pre-commit: v0.15.4 → v0.15.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.4...v0.15.5) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3944a93..fc122a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ default_stages: minimum_pre_commit_version: 2.16.0 repos: - repo: https://github.com/biomejs/pre-commit - rev: v2.4.4 + rev: v2.4.6 hooks: - id: biome-format exclude: ^\.cruft\.json$ # inconsistent indentation with cruft - file never to be modified manually. @@ -16,7 +16,7 @@ repos: hooks: - id: pyproject-fmt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.4 + rev: v0.15.5 hooks: - id: ruff-check args: [--fix, --exit-non-zero-on-fix] From e594d43293551d9c8dab8cdcdefbf11b28419a54 Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Tue, 10 Mar 2026 13:01:52 +0100 Subject: [PATCH 2/4] hm --- pyproject.toml | 8 +-- src/anndata_plot/__init__.py | 15 +----- src/anndata_plot/pl/utils.py | 94 ------------------------------------ tests/test_basic.py | 8 +-- 4 files changed, 6 insertions(+), 119 deletions(-) delete mode 100644 src/anndata_plot/pl/utils.py diff --git a/pyproject.toml b/pyproject.toml index bb9eefa..e4b0c44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ authors = [ { name = "Tim Treis" }, ] -requires-python = ">=3.10" +requires-python = ">=3.12" classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "anndata", - "holoviews", + "hv-anndata", # for debug logging (referenced from the issue template) "session-info2", ] @@ -69,9 +69,9 @@ envs.docs.scripts.clean = "git clean -fdX -- {args:docs}" envs.hatch-test.features = [ "dev", "test" ] envs.hatch-test.matrix = [ # Test the lowest and highest supported Python versions with normal deps - { deps = [ "stable" ], python = [ "3.10", "3.13" ] }, + { deps = [ "stable" ], python = [ "3.14", "3.12" ] }, # Test the newest supported Python version also with pre-release deps - { deps = [ "pre" ], python = [ "3.13" ] }, + { deps = [ "pre" ], python = [ "3.14" ] }, ] # If the matrix variable `deps` is set to "pre", # set the environment variable `UV_PRERELEASE` to "allow". diff --git a/src/anndata_plot/__init__.py b/src/anndata_plot/__init__.py index 5e3d9ab..199a50d 100644 --- a/src/anndata_plot/__init__.py +++ b/src/anndata_plot/__init__.py @@ -1,16 +1,3 @@ -from importlib.metadata import version - -import holoviews as hv - from . import pl, pp, tl -from .pl.utils import AnnDataInterface - -__all__ = ["pl"] - -__version__ = version("anndata-plot") - -# register the AnnDataInterface with holoviews -if AnnDataInterface.datatype not in hv.core.data.datatypes: - hv.core.data.datatypes.append(AnnDataInterface.datatype) -hv.core.Interface.register(AnnDataInterface) +__all__ = ["pl", "pp", "tl"] diff --git a/src/anndata_plot/pl/utils.py b/src/anndata_plot/pl/utils.py deleted file mode 100644 index a8b05d8..0000000 --- a/src/anndata_plot/pl/utils.py +++ /dev/null @@ -1,94 +0,0 @@ -from dataclasses import dataclass -from enum import Enum, auto -from typing import cast, overload - -import anndata as ad -import holoviews as hv -import numpy as np - - -class Raise(Enum): - """Marker sentry for raising an exception.""" - - Sentry = auto() - - -@dataclass -class AnnDataProxy: - """Proxy for anndata, used to get arrays with a mapping-like interface.""" - - # from: https://gist.github.com/flying-sheep/3ff54234019cc7c84e84cbbe649209c5 - - adata: ad.AnnData - - @overload - def get(self, k: str, /, default: None = None) -> np.ndarray | None: ... - @overload - def get(self, k: str, /, default: np.ndarray | Raise) -> np.ndarray: ... - - def get(self, k: str, /, default: np.ndarray | Raise | None = None) -> np.ndarray | None: - """Get an array from an AnnData object.""" - k_orig = k - if "." not in k: - if default is not Raise.Sentry and k not in self.adata.var_names: - return default - return self.adata[:, k].X.flatten() - attr_name, k = k.split(".", 1) - attr = getattr(self.adata, attr_name) - if "." not in k: - if default is not Raise.Sentry and k not in attr: - return default - return attr[k] - k, i = k.split(".", 1) - arr = attr[k] - if "." not in i: - if default is not Raise.Sentry and not (0 <= int(i) < arr.shape[1]): - return default - return arr[:, int(i)] - raise KeyError(k_orig) - - def __contains__(self, k: str) -> bool: - return self.get(k) is not None - - def __getitem__(self, k: str) -> object: - return self.get(k, Raise.Sentry) - - def __len__(self) -> int: - return len(self.adata) - - -class AnnDataInterface(hv.core.Interface): - """Interface for AnnData objects.""" - - types = (ad.AnnData,) - datatype = "anndata" - - @classmethod - def init( - cls, eltype, data: ad.AnnData | AnnDataProxy, kdims: list[str] | None, vdims: list[str] | None - ) -> tuple[AnnDataProxy, dict, dict]: - """Initialize the interface and return dataset and dimensions.""" - proxy = AnnDataProxy(data) if isinstance(data, ad.AnnData) else data - return proxy, {"kdims": kdims, "vdims": vdims}, {} - - @classmethod - def values( - cls, - data: hv.Dataset, - dim: hv.Dimension | str, - expanded=True, - flat=True, - compute=True, - keep_index=False, - ) -> np.ndarray: - """Get the values of a dimension.""" - dim = data.get_dimension(dim) - proxy = cast(AnnDataProxy, data.data) - return proxy[dim.name] - - @classmethod - def dimension_type(cls, data: hv.Dataset, dim: hv.Dimension | str) -> np.dtype: - """Get the dtype of a dimension.""" - dim = data.get_dimension(dim) - proxy = cast(AnnDataProxy, data.data) - return proxy[dim.name].dtype diff --git a/tests/test_basic.py b/tests/test_basic.py index 19d6058..92eb3ad 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1,12 +1,6 @@ import pytest -import anndata_plot - - -def test_package_has_version(): - assert anndata_plot.__version__ is not None - @pytest.mark.skip(reason="This decorator should be removed when test passes.") -def test_example(): +def test_example() -> None: assert 1 == 0 # This test is designed to fail. From b42839b36ecfe4d4c9148afdb1b61bbb34238076 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:02:39 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e4b0c44..c674976 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,8 +17,6 @@ authors = [ requires-python = ">=3.12" classifiers = [ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", From c198c2f449ed11973a5528e57a0a5024710895dd Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Tue, 10 Mar 2026 13:08:30 +0100 Subject: [PATCH 4/4] actually import it --- tests/test_basic.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_basic.py b/tests/test_basic.py index 92eb3ad..05eda61 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1,5 +1,11 @@ import pytest +import anndata_plot + + +def test_all() -> None: + assert set(dir(anndata_plot)) > {"pl", "pp", "tl"} + @pytest.mark.skip(reason="This decorator should be removed when test passes.") def test_example() -> None: