Skip to content

Commit d7f584f

Browse files
Backport PR #1318 on branch 0.12.x (fix: use standard version API) (#2132)
Co-authored-by: Philipp A <flying-sheep@web.de>
1 parent 8d992b1 commit d7f584f

21 files changed

Lines changed: 85 additions & 227 deletions

File tree

.github/workflows/test-cpu.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,6 @@ jobs:
120120
python -m build --sdist --wheel .
121121
twine check dist/*
122122
123-
- name: Check runtime version
124-
run: |
125-
pip install dist/*.whl
126-
python -c 'import anndata; print(anndata.__version__)'
127-
128123
check:
129124
if: always()
130125
needs:

docs/release-notes/1318.fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecate `__version__` and use standard {func}`~importlib.metadata.version` API {user}`flying-sheep`

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ Home-page = "https://github.com/scverse/anndata"
5757

5858
[project.optional-dependencies]
5959
dev = [
60-
# runtime dev version generation
61-
"hatch-vcs",
6260
"anndata[dev-doc]",
6361
]
6462
doc = [
@@ -146,7 +144,9 @@ addopts = [
146144
filterwarnings = [
147145
"ignore::anndata._warnings.OldFormatWarning",
148146
"ignore::anndata._warnings.ExperimentalFeatureWarning",
149-
"ignore:.*first_column_names:FutureWarning:scanpy", # scanpy 1.10.x
147+
"ignore:.*first_column_names:FutureWarning:scanpy", # scanpy 1.10.x
148+
"ignore:Importing read_.* from `anndata` is deprecated:FutureWarning:scanpy",
149+
"ignore:`__version__` is deprecated:FutureWarning:scanpy",
150150
]
151151
# When `--strict-warnings` is used, all warnings are treated as errors, except those:
152152
filterwarnings_when_strict = [

src/anndata/__init__.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from ._core.merge import concat
1313
from ._core.raw import Raw
1414
from ._settings import settings
15-
from ._version import __version__
1615
from ._warnings import (
1716
ExperimentalFeatureWarning,
1817
ImplicitModificationWarning,
@@ -28,30 +27,13 @@
2827
# We use these in tests by attribute access
2928
from . import logging # noqa: F401 # isort: skip
3029

31-
_DEPRECATED_IO = (
32-
"read_loom",
33-
"read_hdf",
34-
"read_excel",
35-
"read_umi_tools",
36-
"read_csv",
37-
"read_text",
38-
"read_mtx",
39-
)
40-
_DEPRECATED = {method: f"io.{method}" for method in _DEPRECATED_IO}
41-
42-
43-
def __getattr__(attr_name: str) -> Any:
44-
return module_get_attr_redirect(attr_name, deprecated_mapping=_DEPRECATED)
45-
46-
4730
__all__ = [
4831
"AnnData",
4932
"ExperimentalFeatureWarning",
5033
"ImplicitModificationWarning",
5134
"OldFormatWarning",
5235
"Raw",
5336
"WriteWarning",
54-
"__version__",
5537
"abc",
5638
"concat",
5739
"experimental",
@@ -63,3 +45,26 @@ def __getattr__(attr_name: str) -> Any:
6345
"types",
6446
"typing",
6547
]
48+
49+
_DEPRECATED_IO = (
50+
"read_loom",
51+
"read_hdf",
52+
"read_excel",
53+
"read_umi_tools",
54+
"read_csv",
55+
"read_text",
56+
"read_mtx",
57+
)
58+
_DEPRECATED = {method: f"io.{method}" for method in _DEPRECATED_IO}
59+
60+
61+
def __getattr__(attr_name: str) -> Any:
62+
if attr_name == "__version__":
63+
import warnings
64+
from importlib.metadata import version
65+
66+
msg = "`__version__` is deprecated, use `importlib.metadata.version('anndata')` instead."
67+
warnings.warn(msg, FutureWarning, stacklevel=2)
68+
return version("anndata")
69+
70+
return module_get_attr_redirect(attr_name, deprecated_mapping=_DEPRECATED)

src/anndata/_core/merge.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414

1515
import numpy as np
1616
import pandas as pd
17-
import scipy
1817
from natsort import natsorted
19-
from packaging.version import Version
2018
from scipy import sparse
2119

2220
from anndata._core.file_backing import to_memory
@@ -30,7 +28,6 @@
3028
CupyCSRMatrix,
3129
CupySparseMatrix,
3230
DaskArray,
33-
_map_cat_to_str,
3431
)
3532
from ..utils import asarray, axis_len, warn_once
3633
from .anndata import AnnData
@@ -185,15 +182,6 @@ def equal_sparse(a, b) -> bool:
185182
# Comparison broken for CSC matrices
186183
# https://github.com/cupy/cupy/issues/7757
187184
a, b = CupyCSRMatrix(a), CupyCSRMatrix(b)
188-
if Version(scipy.__version__) >= Version("1.16.0rc1"):
189-
# TODO: https://github.com/scipy/scipy/issues/23068
190-
return bool(
191-
a.format == b.format
192-
and (a.shape == b.shape)
193-
and np.all(a.indptr == b.indptr)
194-
and np.all(a.indices == b.indices)
195-
and np.all((a.data == b.data) | (np.isnan(a.data) & np.isnan(b.data)))
196-
)
197185
comp = a != b
198186
if isinstance(comp, bool):
199187
return not comp
@@ -1646,7 +1634,7 @@ def concat( # noqa: PLR0912, PLR0913, PLR0915
16461634
)
16471635
if index_unique is not None:
16481636
concat_indices = concat_indices.str.cat(
1649-
_map_cat_to_str(label_col), sep=index_unique
1637+
label_col.map(str, na_action="ignore"), sep=index_unique
16501638
)
16511639
concat_indices = pd.Index(concat_indices)
16521640

src/anndata/_core/sparse_dataset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
from abc import ABC
1717
from collections.abc import Iterable
1818
from functools import cached_property
19+
from importlib.metadata import version
1920
from itertools import accumulate, chain, pairwise
2021
from math import floor
2122
from pathlib import Path
2223
from typing import TYPE_CHECKING, NamedTuple
2324

2425
import h5py
2526
import numpy as np
26-
import scipy
2727
import scipy.sparse as ss
2828
from packaging.version import Version
2929
from scipy.sparse import _sparsetools
@@ -54,7 +54,7 @@
5454
from scipy.sparse import spmatrix as _cs_matrix
5555

5656

57-
SCIPY_1_15 = Version(scipy.__version__) >= Version("1.15rc0")
57+
SCIPY_1_15 = Version(version("scipy")) >= Version("1.15rc0")
5858

5959

6060
class BackedFormat(NamedTuple):

src/anndata/_io/h5ad.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
from .specs import read_elem, write_elem
2828
from .specs.registry import IOSpec, write_spec
2929
from .utils import (
30-
H5PY_V3,
3130
_read_legacy_raw,
3231
idx_chunks_along_axis,
3332
no_write_dataset_2d,
@@ -324,16 +323,12 @@ def read_dataframe_legacy(dataset: h5py.Dataset) -> pd.DataFrame:
324323
"Consider rewriting it."
325324
)
326325
warn(msg, OldFormatWarning, stacklevel=2)
327-
if H5PY_V3:
328-
df = pd.DataFrame(
329-
_decode_structured_array(
330-
_from_fixed_length_strings(dataset[()]), dtype=dataset.dtype
331-
)
326+
df = pd.DataFrame(
327+
_decode_structured_array(
328+
_from_fixed_length_strings(dataset[()]), dtype=dataset.dtype
332329
)
333-
else:
334-
df = pd.DataFrame(_from_fixed_length_strings(dataset[()]))
335-
df.set_index(df.columns[0], inplace=True)
336-
return df
330+
)
331+
return df.set_index(df.columns[0])
337332

338333

339334
def read_dataframe(group: h5py.Group | h5py.Dataset) -> pd.DataFrame:
@@ -346,10 +341,9 @@ def read_dataframe(group: h5py.Group | h5py.Dataset) -> pd.DataFrame:
346341

347342
@report_read_key_on_error
348343
def read_dataset(dataset: h5py.Dataset):
349-
if H5PY_V3:
350-
string_dtype = h5py.check_string_dtype(dataset.dtype)
351-
if (string_dtype is not None) and (string_dtype.encoding == "utf-8"):
352-
dataset = dataset.asstr()
344+
string_dtype = h5py.check_string_dtype(dataset.dtype)
345+
if (string_dtype is not None) and (string_dtype.encoding == "utf-8"):
346+
dataset = dataset.asstr()
353347
value = dataset[()]
354348
if not hasattr(value, "dtype"):
355349
return value
@@ -362,10 +356,9 @@ def read_dataset(dataset: h5py.Dataset):
362356
return value[0]
363357
elif len(value.dtype.descr) > 1: # Compound dtype
364358
# For backwards compat, now strings are written as variable length
365-
dtype = value.dtype
366-
value = _from_fixed_length_strings(value)
367-
if H5PY_V3:
368-
value = _decode_structured_array(value, dtype=dtype)
359+
value = _decode_structured_array(
360+
_from_fixed_length_strings(value), dtype=value.dtype
361+
)
369362
if value.shape == ():
370363
value = value[()]
371364
return value

src/anndata/_io/specs/methods.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from collections.abc import Mapping
55
from copy import copy
66
from functools import partial
7+
from importlib.metadata import version
78
from itertools import product
89
from types import MappingProxyType
910
from typing import TYPE_CHECKING
@@ -21,7 +22,7 @@
2122
from anndata._core.index import _normalize_indices
2223
from anndata._core.merge import intersect_keys
2324
from anndata._core.sparse_dataset import _CSCDataset, _CSRDataset, sparse_dataset
24-
from anndata._io.utils import H5PY_V3, check_key, zero_dim_array_as_scalar
25+
from anndata._io.utils import check_key, zero_dim_array_as_scalar
2526
from anndata._warnings import OldFormatWarning
2627
from anndata.compat import (
2728
NULLABLE_NUMPY_STRING_TYPE,
@@ -609,7 +610,7 @@ def write_vlen_string_array_zarr(
609610
if is_zarr_v2():
610611
import numcodecs
611612

612-
if Version(numcodecs.__version__) < Version("0.13"):
613+
if Version(version("numcodecs")) < Version("0.13"):
613614
msg = "Old numcodecs version detected. Please update for improved performance and stability."
614615
warnings.warn(msg, UserWarning, stacklevel=2)
615616
# Workaround for https://github.com/zarr-developers/numcodecs/issues/514
@@ -665,10 +666,9 @@ def _to_hdf5_vlen_strings(value: np.ndarray) -> np.ndarray:
665666
@_REGISTRY.register_read(ZarrArray, IOSpec("rec-array", "0.2.0"))
666667
def read_recarray(d: ArrayStorageType, *, _reader: Reader) -> np.recarray | npt.NDArray:
667668
value = d[()]
668-
dtype = value.dtype
669-
value = _from_fixed_length_strings(value)
670-
if H5PY_V3:
671-
value = _decode_structured_array(value, dtype=dtype)
669+
value = _decode_structured_array(
670+
_from_fixed_length_strings(value), dtype=value.dtype
671+
)
672672
return value
673673

674674

src/anndata/_io/utils.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
from __future__ import annotations
22

3+
from collections.abc import Callable
34
from functools import WRAPPER_ASSIGNMENTS, wraps
45
from itertools import pairwise
5-
from typing import TYPE_CHECKING, cast
6+
from typing import TYPE_CHECKING, Literal, cast
67
from warnings import warn
78

8-
import h5py
9-
from packaging.version import Version
10-
119
from .._core.sparse_dataset import BaseCompressedSparseDataset
1210

1311
if TYPE_CHECKING:
@@ -21,9 +19,6 @@
2119

2220
Storage = StorageType | BaseCompressedSparseDataset
2321

24-
# For allowing h5py v3
25-
# https://github.com/scverse/anndata/issues/442
26-
H5PY_V3 = Version(h5py.__version__).major >= 3
2722

2823
# -------------------------------------------------------------------------------
2924
# Type conversion

src/anndata/_version.py

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)