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
68 changes: 25 additions & 43 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,6 @@
typehints_defaults = "braces"
always_use_bars_union = True # use `|`, not `Union` in types even when on Python ≤3.14
todo_include_todos = False
nitpicky = True # Report broken links
nitpick_ignore = [ # APIs without an intersphinx entry
# These APIs aren’t actually documented
("py:class", "anndata._core.raw.Raw"),
("py:class", "pandas.api.typing.NAType"),
# TODO: remove zappy support; the zappy repo is archived
("py:class", "anndata.compat.ZappyArray"),
]


def setup(app: Sphinx):
Expand Down Expand Up @@ -142,55 +134,45 @@ def res(
zarrs=("https://zarrs-python.readthedocs.io/en/stable/", None),
)

# Fix mis-documented types. Use `anndata.utils.set_module` for ours instead.
qualname_overrides = {
#### stdlib
"types.EllipsisType": ("py:data", "Ellipsis"),
"h5py._hl.group.Group": "h5py.Group",
"h5py._hl.files.File": "h5py.File",
"h5py._hl.dataset.Dataset": "h5py.Dataset",
"anndata._core.anndata.AnnData": "anndata.AnnData",
#### anndata
**{
f"anndata._core.aligned_mapping.{cls}{kind}": "collections.abc.Mapping"
for cls in ["Layers", "AxisArrays", "PairwiseArrays"]
for kind in ["", "View"]
},
"anndata._types.ReadCallback": "anndata.experimental.ReadCallback",
"anndata._types.WriteCallback": "anndata.experimental.WriteCallback",
"anndata._types.Read": "anndata.experimental.Read",
"anndata._types.Write": "anndata.experimental.Write",
"anndata._types.StorageType": "anndata.experimental.StorageType",
"anndata._types.Dataset2DIlocIndexer": "anndata.experimental.Dataset2DIlocIndexer",
"zarr.core.array.Array": "zarr.Array",
"zarr.core.group.Group": "zarr.Group",
# Buffer is not yet exported, so the buffer class registry is the closest thing
"zarr.core.buffer.core.Buffer": "zarr.registry.Registry",
"zarr.storage._common.StorePath": "zarr.storage.StorePath",
"anndata.compat.DaskArray": "dask.array.Array",
"anndata.compat.CupyArray": "cupy.ndarray",
"anndata.compat.CupySparseMatrix": "cupyx.scipy.sparse.spmatrix",
"anndata.compat.XDataArray": "xarray.DataArray",
"anndata.compat.XDataset": "xarray.Dataset",
# Can’t use `set_module` for `type`s. When moving out of .experimental, define in actual location.
"anndata.compat.Index": "anndata.typing.Index",
"anndata._types.StorageType": "anndata.experimental.StorageType",
# https://github.com/theislab/scanpydoc/issues/254
"anndata.typing.RWAble": "anndata.typing.RWAble",
"anndata.typing.AxisStorable": "anndata.typing.AxisStorable",
#### h5py
"h5py._hl.group.Group": "h5py.Group",
"h5py._hl.files.File": "h5py.File",
"h5py._hl.dataset.Dataset": "h5py.Dataset",
#### arrays
"awkward.highlevel.Array": "ak.Array",
"numpy.int64": ("py:attr", "numpy.int64"),
"numpy.dtypes.StringDType": ("py:attr", "numpy.dtypes.StringDType"),
"pandas.DataFrame.iloc": ("py:attr", "pandas.DataFrame.iloc"),
"pandas.DataFrame.loc": ("py:attr", "pandas.DataFrame.loc"),
"pandas.core.series.Series": "pandas.Series",
"pandas.core.arrays.categorical.Categorical": "pandas.Categorical",
"pandas.core.arrays.base.ExtensionArray": "pandas.api.extensions.ExtensionArray",
"pandas.core.dtypes.dtypes.BaseMaskedDtype": "pandas.api.extensions.ExtensionDtype",
}
autodoc_type_aliases = dict(
NDArray=":data:`~numpy.typing.NDArray`",
AxisStorable=":data:`~anndata.typing.AxisStorable`",
# The following are TypeVars in `anndata._types`, and aren’t actually exported,
# yet this bug causes them to create issues:
# - https://github.com/python/cpython/issues/124089
# - https://github.com/tox-dev/sphinx-autodoc-typehints/issues/580
K=":class:`zarr.Array` | :class:`h5py.Dataset`",
S=":class:`anndata.experimental.StorageType`",
RWAble=":class:`anndata.typing.RWAble`",
)
# Sphinx consults this {alias → name} mapping when rendering types
# sphinx-autodoc-typehints uses when importing types to resolve them
autodoc_type_aliases = dict()
# if nothing else helps, modify `nitpick_ignore`
nitpicky = True # Report broken links, this stays on
nitpick_ignore = [ # APIs without an intersphinx entry
# These APIs aren’t actually documented
("py:class", "anndata._core.raw.Raw"),
("py:class", "pandas.api.typing.NAType"),
# TODO: remove zappy support; the zappy repo is archived
("py:class", "anndata.compat.ZappyArray"),
]

# -- Social cards ---------------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ doc = [
"myst-parser",
"sphinx-design",
"anndata[dask]",
"pandas>=3",
# for unreleased changes
{ include-group = "dev-doc" },
]
Expand Down
2 changes: 2 additions & 0 deletions src/anndata/_core/anndata.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
deprecation_msg,
ensure_df_homogeneous,
raise_value_error_if_multiindex_columns,
set_module,
warn,
)
from .access import ElementRef
Expand All @@ -66,6 +67,7 @@
from .index import Index


@set_module("anndata")
class AnnData(metaclass=utils.DeprecationMixinMeta): # noqa: PLW1641
"""\
An annotated data matrix.
Expand Down
9 changes: 9 additions & 0 deletions src/anndata/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from . import typing
from .compat import H5Array, H5Group, ZarrArray, ZarrGroup
from .utils import set_module

if TYPE_CHECKING:
from collections.abc import Mapping
Expand All @@ -22,6 +23,9 @@
Reader,
Writer,
)
else: # https://github.com/tox-dev/sphinx-autodoc-typehints/issues/580
type S = StorageType
type RWAble = typing.RWAble


__all__ = [
Expand All @@ -40,6 +44,7 @@
type StorageType = ArrayStorageType | GroupStorageType


@set_module("anndata.experimental")
class Dataset2DIlocIndexer(Protocol):
def __getitem__(self, idx: Any) -> Dataset2D: ...

Expand All @@ -58,6 +63,7 @@ def __call__(
) -> LazyDataStructures: ...


@set_module("anndata.experimental")
class Read[S: StorageType, RWAble: typing.RWAble](Protocol):
def __call__(self, elem: S) -> RWAble:
"""Low-level reading function for an element.
Expand Down Expand Up @@ -104,6 +110,7 @@ def __call__(
) -> None: ...


@set_module("anndata.experimental")
class Write[RWAble: typing.RWAble](Protocol):
def __call__(
self,
Expand All @@ -129,6 +136,7 @@ def __call__(
...


@set_module("anndata.experimental")
class ReadCallback[S: StorageType, RWAble: typing.RWAble](Protocol):
def __call__(
self,
Expand Down Expand Up @@ -160,6 +168,7 @@ def __call__(
...


@set_module("anndata.experimental")
class WriteCallback[RWAble: typing.RWAble](Protocol):
def __call__(
self,
Expand Down
32 changes: 7 additions & 25 deletions src/anndata/compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class Empty(Enum):
#############################
# Optional deps
#############################


@cache
def is_zarr_v2() -> bool:
return Version(version("zarr")) < Version("3.0.0")
Expand Down Expand Up @@ -131,11 +133,7 @@ def __repr__():
elif find_spec("dask"):
from dask.array import Array as DaskArray
else:

class DaskArray:
@staticmethod
def __repr__():
return "mock dask.array.core.Array"
DaskArray = type("Array", (), dict(__module__="dask.array"))


if find_spec("xarray") or TYPE_CHECKING:
Expand Down Expand Up @@ -179,26 +177,10 @@ def is_cupy_importable() -> bool:
da.register_chunk_type(CupyCSRMatrix)
da.register_chunk_type(CupyCSCMatrix)
else:

class CupySparseMatrix:
@staticmethod
def __repr__():
return "mock cupyx.scipy.sparse.spmatrix"

class CupyCSRMatrix:
@staticmethod
def __repr__():
return "mock cupyx.scipy.sparse.csr_matrix"

class CupyCSCMatrix:
@staticmethod
def __repr__():
return "mock cupyx.scipy.sparse.csc_matrix"

class CupyArray:
@staticmethod
def __repr__():
return "mock cupy.ndarray"
CupyArray = type("ndarray", (), dict(__module__="cupy"))
CupySparseMatrix = type("spmatrix", (), dict(__module__="cupyx.scipy.sparse"))
CupyCSRMatrix = type("csr_matrix", (), dict(__module__="cupyx.scipy.sparse"))
CupyCSCMatrix = type("csc_matrix", (), dict(__module__="cupyx.scipy.sparse"))


old_positionals = partial(legacy_api, category=FutureWarning)
Expand Down
2 changes: 2 additions & 0 deletions src/anndata/experimental/backed/_lazy_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
if TYPE_CHECKING: # Double nesting so Sphinx can import the parent block
from xarray.core.extension_array import PandasExtensionArray
from xarray.core.indexing import ExplicitIndexer
else: # https://github.com/tox-dev/sphinx-autodoc-typehints/issues/580
type K = H5Array | ZarrArray


class ZarrOrHDF5Wrapper[K: (H5Array | H5AsTypeView, ZarrArray)](XZarrArrayWrapper):
Expand Down
11 changes: 10 additions & 1 deletion src/anndata/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import warnings
from functools import partial, singledispatch
from types import FunctionType
from typing import TYPE_CHECKING

import h5py
Expand All @@ -19,7 +20,7 @@
from .logging import get_logger

if TYPE_CHECKING:
from collections.abc import Iterable, Mapping, Sequence
from collections.abc import Callable, Iterable, Mapping, Sequence
from typing import Any, Literal, LiteralString

logger = get_logger(__name__)
Expand Down Expand Up @@ -408,6 +409,14 @@ def is_hidden(attr: object) -> bool:
]


def set_module[C: FunctionType | type](name: str, /) -> Callable[[C], C]:
def decorator(f: C) -> C:
f.__module__ = name
return f

return decorator


def raise_value_error_if_multiindex_columns(df: pd.DataFrame, attr: str):
if isinstance(df.columns, pd.MultiIndex):
msg = (
Expand Down