Skip to content
Open
33 changes: 25 additions & 8 deletions ci/scripts/low-vers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from contextlib import ExitStack
from functools import cached_property
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, assert_never

import dependency_groups
from packaging.requirements import Requirement
Expand Down Expand Up @@ -93,6 +93,7 @@ class Args(argparse.Namespace):
output: Path | None
_extras: list[str]
_all_extras: bool
_skip_extras: list[str]
_groups: list[str]
_all_groups: bool

Expand Down Expand Up @@ -121,7 +122,7 @@ def parser(cls) -> argparse.ArgumentParser:
dest="_extras",
metavar="EXTRA",
type=str,
nargs="*",
nargs="+",
default=(),
help="extras to install",
)
Expand All @@ -131,6 +132,15 @@ def parser(cls) -> argparse.ArgumentParser:
action="store_true",
help="get all extras",
)
parser.add_argument(
"--skip-extras",
dest="_skip_extras",
metavar="EXTRA",
type=str,
nargs="+",
default=(),
help="extras to skip when `--all-extras` is set",
)
parser.add_argument(
"--groups",
dest="_groups",
Expand Down Expand Up @@ -167,13 +177,20 @@ def pyproject(self) -> dict[str, Any]:
@cached_property
def extras(self) -> AbstractSet[str]:
"""Return the extras to install."""
if self._extras:
if self._all_extras:
match self._extras, self._all_extras, self._skip_extras:
case [], True, skip:
return dict.fromkeys(
self.pyproject["project"]["optional-dependencies"].keys()
- set(skip)
).keys()
case extras, False, []:
return dict.fromkeys(extras).keys()
case _, True, _:
sys.exit("Cannot specify both --extras and --all-extras")
return dict.fromkeys(self._extras).keys()
if not self._all_extras:
return set()
return self.pyproject["project"]["optional-dependencies"].keys()
case _, False, _:
sys.exit("Cannot specify --skip-extras without --all-extras")
case never:
assert_never(never)

@cached_property
def groups(self) -> AbstractSet[str]:
Expand Down
5 changes: 4 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import os
import shutil
import sys
from datetime import datetime
Expand Down Expand Up @@ -126,6 +127,7 @@
nb_execution_excludepatterns = [
f"{d}{'/*' * n}" for d in ["tutorials", "how-to"] for n in (1, 2, 3)
]
nb_execution_show_tb = bool(os.environ.get("READTHEDOCS"))
nb_merge_streams = True

ogp_site_url = "https://scanpy.scverse.org/en/stable/"
Expand All @@ -140,7 +142,8 @@
katex_prerender = shutil.which(NODEJS_BINARY) is not None

intersphinx_mapping = dict(
anndata=("https://anndata.scverse.org/en/stable/", None),
# Needs latest until `.acc` is released in 0.13
anndata=("https://anndata.scverse.org/en/latest/", None),
bbknn=("https://bbknn.readthedocs.io/en/latest/", None),
cuml=("https://docs.rapids.ai/api/cuml/stable/", None),
cycler=("https://matplotlib.org/cycler/", None),
Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/1.6.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ This release includes an overhaul of {func}`~scanpy.pl.dotplot`, {func}`~scanpy.

#### Additions

- {func}`~anndata.concat` is now exported from scanpy, see {doc}`anndata:concatenation` for more info. {pr}`1338` {smaller}`I Virshup`
- {func}`~anndata.concat` is now exported from scanpy, see {doc}`anndata:tutorials/concatenation` for more info. {pr}`1338` {smaller}`I Virshup`
- Added highly variable gene selection strategy from Seurat v3 {pr}`1204` {smaller}`A Gayoso`
- Added [CellRank](https://github.com/theislab/cellrank/) to scanpy ecosystem {pr}`1304` {smaller}`giovp`
- Added `backup_url` param to {func}`~scanpy.read_10x_h5` {pr}`1296` {smaller}`A Gayoso`
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/4199.feat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add {mod}`anndata.acc` support to {func}`scanpy.get.aggregate`. {smaller}`P Angerer`
3 changes: 2 additions & 1 deletion hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ overrides.matrix.deps.env-vars = [
overrides.matrix.deps.pre-install-commands = [
{ if = [
"low-vers",
], value = "uv run ci/scripts/low-vers.py pyproject.toml --all-extras --groups=test -o ci/scanpy-low-vers.txt" },
], value = "uv run ci/scripts/low-vers.py pyproject.toml --all-extras --skip-extras=scanpy2 --groups=test -o ci/scanpy-low-vers.txt" },
]
overrides.matrix.deps.python = [
{ if = [ "low-vers" ], value = "3.12" },
]
overrides.matrix.deps.extra-dependencies = [
{ if = [ "stable" ], value = "scipy>=1.17" },
{ if = [ "pre" ], value = "scanpy[scanpy2]" },
{ if = [ "pre" ], value = "anndata @ git+https://github.com/scverse/anndata.git" },
{ if = [ "pre" ], value = "pandas>=3" },
]
Expand Down
12 changes: 7 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ scrublet = [ "scikit-image>=0.25" ]
# highly_variable_genes method 'seurat_v3'
skmisc = [ "scikit-misc>=0.5.1" ]
illico = [ "illico>=0.6" ]
scanpy2 = [ "igraph>=0.10.8", "scanpy[illico]", "scikit-misc>=0.5.1" ]
scanpy2 = [ "anndata>=0.13", "igraph>=0.10.8", "scanpy[illico]", "scikit-misc>=0.5.1" ]

[dependency-groups]
dev = [
Expand All @@ -118,14 +118,14 @@ test = [
{ include-group = "test-min" },
]
docs = [
"ipython>=8.27", # for nbsphinx code highlighting
"ipython>=8.27", # for nbsphinx code highlighting
"myst-nb>=1.4",
"myst-parser>=2",
"nbsphinx>=0.9",
"numpy>=2.4", # type aliases
"numpy>=2.4", # type aliases
"sam-algorithm",
# TODO: remove necessity for being able to import doc-linked classes
"scanpy[dask-ml,leiden,paga,plotting]",
"scanpy[dask-ml,leiden,paga,plotting,scanpy2,scrublet]",
"scanpydoc>=0.16.1",
"scverse-misc[sphinx]",
"sphinx>=9.1",
Expand All @@ -137,7 +137,7 @@ docs = [
"sphinx-issues>=5.0.1",
"sphinxcontrib-bibtex",
"sphinxcontrib-katex",
"sphinxext-opengraph", # for nice cards when sharing on social
"sphinxext-opengraph", # for nice cards when sharing on social
]
test-min = [
"dependency-groups", # for CI scripts doctests
Expand Down Expand Up @@ -274,6 +274,8 @@ filterwarnings = [
"ignore:is_categorical_dtype is deprecated:FutureWarning",
# Ignore numba PEP 456 warning specific to ARM machines
"ignore:FNV hashing is not implemented in Numba.*:UserWarning",
# Ignore numba macOS warnings
"ignore:Detected unsupported threading environment:UserWarning",
# we want to see and eventually fix these
"default::numba.core.errors.NumbaPerformanceWarning",
# we should set init=obsm["X_pca"] or so
Expand Down
13 changes: 10 additions & 3 deletions src/scanpy/_settings/presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import re
from contextlib import contextmanager
from dataclasses import dataclass
from functools import cached_property, partial, wraps
from functools import cache, cached_property, partial, wraps
from importlib.metadata import distributions, requires
from typing import TYPE_CHECKING, Literal, NamedTuple

Expand All @@ -17,8 +17,11 @@

if TYPE_CHECKING:
from collections.abc import Callable, Generator, Mapping
from collections.abc import Set as AbstractSet
from typing import Self

from packaging.utils import NormalizedName


__all__ = [
"DETest",
Expand Down Expand Up @@ -312,14 +315,18 @@ def check(self) -> Self:
return self


@cache
def dist_names() -> AbstractSet[NormalizedName]:
return dict.fromkeys(canonicalize_name(d.name) for d in distributions()).keys()


def _missing_scanpy2_deps() -> list[Requirement]:
dist_names = {canonicalize_name(d.name) for d in distributions()}
return [
r
for r in map(Requirement, requires("scanpy") or ())
if r.marker
and r.marker.evaluate({"extra": "scanpy2"}, "requirement")
and canonicalize_name(r.name) not in dist_names
and canonicalize_name(r.name) not in dist_names()
]


Expand Down
Loading
Loading