Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/4191.chore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{mod}`anndata` is lower bounded by `0.11.2` {smaller}`I Gold`
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ classifiers = [
]
dynamic = [ "version" ]
dependencies = [
"anndata>=0.10.8",
"anndata>=0.11.2",
"certifi",
"fast-array-utils[accel,sparse]>=1.4",
"h5py>=3.11",
Expand All @@ -67,7 +67,7 @@ dependencies = [
"patsy",
"pynndescent>=0.5.13",
"scikit-learn>=1.6",
"scipy>=1.14",
"scipy>=1.15",
"scverse-misc[settings]>=0.1.1",
"seaborn>=0.13.2",
"session-info2",
Expand Down
21 changes: 4 additions & 17 deletions src/scanpy/_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@
import numpy as np
import pandas as pd
from anndata._core.sparse_dataset import BaseCompressedSparseDataset
from packaging.version import Version

from .. import logging as logg
from .._compat import CSBase, DaskArray, SpBase, _CSArray, pkg_version, warn
from .._compat import CSBase, DaskArray, SpBase, warn
from ._numba import _numba_thread_limit

if TYPE_CHECKING:
Expand Down Expand Up @@ -728,21 +727,9 @@ def axis_nnz(x: ArrayLike, /, axis: Literal[0, 1]) -> np.ndarray:
return np.count_nonzero(x, axis=axis)


if pkg_version("scipy") >= Version("1.15"):
# newer scipy versions support the `axis` argument for count_nonzero
@axis_nnz.register(CSBase)
def _(x: CSBase, /, axis: Literal[0, 1]) -> np.ndarray:
return x.count_nonzero(axis=axis)

else:
# older scipy versions don’t have any way to get the nnz of a sparse array
@axis_nnz.register(CSBase)
def _(x: CSBase, /, axis: Literal[0, 1]) -> np.ndarray:
if isinstance(x, _CSArray):
from scipy.sparse import csc_array, csr_array # noqa: TID251

x = (csr_array if x.format == "csr" else csc_array)(x)
return x.getnnz(axis=axis)
@axis_nnz.register(CSBase)
def _(x: CSBase, /, axis: Literal[0, 1]) -> np.ndarray:
return x.count_nonzero(axis=axis)


@axis_nnz.register(DaskArray)
Expand Down
11 changes: 2 additions & 9 deletions src/testing/scanpy/_helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
from packaging.version import Version

import scanpy as sc
from scanpy._compat import DaskArray, pkg_version

if TYPE_CHECKING:
from collections.abc import Iterable

from numpy.typing import NDArray

from scanpy._compat import DaskArray


# TODO: Report more context on the fields being compared on error
# TODO: Allow specifying paths to ignore on comparison
Expand Down Expand Up @@ -128,14 +129,6 @@ def as_dense_dask_array(*args, **kwargs) -> DaskArray:
from anndata.tests.helpers import as_dense_dask_array

a = as_dense_dask_array(*args, **kwargs)
# Newer versions of as_dense_dask_array chunk all axes by halve when the input is not a dask array.
if (
pkg_version("anndata") < Version("0.11")
and not isinstance(args[0], DaskArray) # keep chunksize intact
):
from anndata.tests.helpers import _half_chunk_size

a = a.rechunk(_half_chunk_size(a.shape))
return a


Expand Down
2 changes: 1 addition & 1 deletion src/testing/scanpy/_pytest/fixtures/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def random_csr(rng: np.random.Generator, size: tuple[int, int]) -> CSRBase:


@pytest.fixture(
params=[np.random.Generator.standard_normal, random_csr], ids=["sparse", "dense"]
params=[np.random.Generator.standard_normal, random_csr], ids=["dense", "sparse"]
)
def backed_adata(request: pytest.FixtureRequest, tmp_path: Path) -> AnnData:
rng = np.random.default_rng()
Expand Down
7 changes: 1 addition & 6 deletions src/testing/scanpy/_pytest/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
from ....scanpy._compat import DaskArray


skipif_no_sparray = pytest.mark.skipif(
Version(version("anndata")) < Version("0.11"),
reason="scipy cs{rc}_array not supported in anndata<0.11",
)

anndata_test_utils_supports_typ_kwarg = Version(version("anndata")) >= Version("0.12.6")


Expand Down Expand Up @@ -84,7 +79,7 @@ def wrapper(a: np.ndarray) -> DaskArray:
("mem", "sparse"): (
pytest.param(sparse.csr_matrix, id="scipy_csr_mat"), # noqa: TID251
pytest.param(sparse.csc_matrix, id="scipy_csc_mat"), # noqa: TID251
pytest.param(sparse.csr_array, id="scipy_csr_arr", marks=[skipif_no_sparray]), # noqa: TID251
pytest.param(sparse.csr_array, id="scipy_csr_arr"), # noqa: TID251
),
("dask", "dense"): tuple(
pytest.param(
Expand Down
16 changes: 3 additions & 13 deletions tests/test_aggregated.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
import numpy as np
import pandas as pd
import pytest
from packaging.version import Version
from scipy import sparse

import scanpy as sc
from scanpy._compat import DaskArray, pkg_version
from scanpy._compat import DaskArray
from scanpy._utils import _resolve_axis, get_literal_vals
from scanpy.get._aggregated import AggType
from testing.scanpy._helpers import assert_equal
Expand Down Expand Up @@ -84,19 +83,10 @@ def test_aggregate_vs_pandas(
remove_unused_categories: bool,
) -> None:
adata = pbmc3k_processed().raw.to_adata()
anndata_has_settings = pkg_version("anndata") >= Version("0.11")
cat_col = adata.obs["louvain"]
categories = cat_col.cat.categories
if anndata_has_settings:
with ad.settings.override(remove_unused_categories=remove_unused_categories):
adata = adata[cat_col.isin(categories[:5]), :1_000].copy()
else:
del adata.obs["louvain"]
mask = cat_col.isin(categories[:5])
adata = adata[mask, :1_000].copy()
adata.obs["louvain"] = cat_col[mask]
if remove_unused_categories:
adata.obs["louvain"] = adata.obs["louvain"].cat.remove_unused_categories()
with ad.settings.override(remove_unused_categories=remove_unused_categories):
adata = adata[cat_col.isin(categories[:5]), :1_000].copy()
adata.X = array_type(adata.X)
if with_na:
nas = list(range(0, adata.shape[0], 5))
Expand Down
Loading