diff --git a/docs/release-notes/1736.bugfix.md b/docs/release-notes/1736.bugfix.md new file mode 100644 index 000000000..58cd65448 --- /dev/null +++ b/docs/release-notes/1736.bugfix.md @@ -0,0 +1,2 @@ +Ensure that views of AwkwardArrays have their "view" attributes removed on saving an {class}`~anndata.AnnData` object +to disk. {user}`grst` diff --git a/src/anndata/_io/specs/methods.py b/src/anndata/_io/specs/methods.py index 8e02b9283..582245310 100644 --- a/src/anndata/_io/specs/methods.py +++ b/src/anndata/_io/specs/methods.py @@ -2,6 +2,7 @@ import warnings from collections.abc import Mapping +from copy import copy from functools import partial from itertools import product from types import MappingProxyType @@ -792,6 +793,9 @@ def write_awkward( from anndata.compat import awkward as ak group = f.require_group(k) + if isinstance(v, views.AwkwardArrayView): + # copy to remove the view attributes + v = copy(v) form, length, container = ak.to_buffers(ak.to_packed(v)) group.attrs["length"] = length group.attrs["form"] = form.to_json() diff --git a/tests/test_awkward.py b/tests/test_awkward.py index 0e2254afe..4b3f81d8e 100644 --- a/tests/test_awkward.py +++ b/tests/test_awkward.py @@ -15,6 +15,7 @@ ImplicitModificationWarning, read_h5ad, ) +from anndata.compat import AwkArray from anndata.compat import awkward as ak from anndata.tests.helpers import assert_equal, gen_adata, gen_awkward from anndata.utils import axis_len @@ -249,6 +250,22 @@ def test_awkward_io(tmp_path, array): assert_equal(adata.uns["awk"], adata2.uns["awk"], exact=True) +def test_awkward_io_view(tmp_path): + """Check that views are converted to actual arrays on save, i.e. the _view_args and __list__ parameters are removed""" + adata = gen_adata((3, 3), varm_types=(), obsm_types=(AwkArray,), layers_types=()) + + v = adata[1:] + adata_path = tmp_path / "adata.h5ad" + v.write_h5ad(adata_path) + + adata2 = read_h5ad(adata_path) + # parameters are not fully removed, but set to None + assert ak.parameters(adata2.obsm["awk_2d_ragged"]) == { + "__list__": None, + "_view_args": None, + } + + # @pytest.mark.parametrize("join", ["outer", "inner"]) @pytest.mark.parametrize( ("arrays", "join", "expected"),