anndata 0.12.8__tar.gz → 0.12.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {anndata-0.12.8 → anndata-0.12.10}/PKG-INFO +2 -2
- anndata-0.12.10/docs/release-notes/0.12.10.md +6 -0
- anndata-0.12.10/docs/release-notes/0.12.9.md +6 -0
- {anndata-0.12.8 → anndata-0.12.10}/pyproject.toml +3 -1
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/anndata.py +73 -61
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/specs/methods.py +18 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_settings.py +21 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_settings.pyi +2 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_elementwise.py +107 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_x.py +27 -7
- {anndata-0.12.8 → anndata-0.12.10}/.cirun.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.codecov.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.cruft.json +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.editorconfig +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/ISSUE_TEMPLATE/enhancement-request.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/dependabot.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/benchmark.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/check-pr.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/close-stale.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/codespell.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/label-stale.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/publish.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/test-cpu.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.github/workflows/test-gpu.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.gitignore +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.gitmodules +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.pre-commit-config.yaml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.readthedocs.yml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.taplo.toml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.vscode/launch.json +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/.vscode/settings.json +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/LICENSE +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/README.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/README.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/asv.conf.json +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/anndata.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/backed_hdf5.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/dataset2d.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/readwrite.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/sparse_dataset.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/benchmarks/benchmarks/utils.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/biome.jsonc +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/ci/constraints.txt +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/ci/min-constraints.txt +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/ci/scripts/min-deps.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/ci/scripts/towncrier_automation.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/Makefile +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/_key_contributors.rst +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/_static/img/anndata_schema.svg +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/_templates/autosummary/class.rst +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/api.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/benchmark-read-write.ipynb +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/benchmarks.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/concatenation.rst +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/conf.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/contributing.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/extensions/autosummary_skip_inherited.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/extensions/no_skip_abc_members.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/extensions/patch_myst_cite.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/fileformat-prose.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/index.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/interoperability.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/references.rst +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.1.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.2.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.3.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.4.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.5.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.6.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.7.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.8.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.10.9.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.11.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.11.1.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.11.2.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.11.3.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.11.4.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.1.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.2.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.3.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.4.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.5.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.6.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.7.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.12.8.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.4.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.5.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.6.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.6.x.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.2.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.3.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.4.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.5.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.6.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.7.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.7.8.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.8.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.9.0.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.9.1.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/0.9.2.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/2172.bug.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/release-notes/index.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/tutorials/index.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/docs/tutorials/zarr-v3.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/hatch.toml +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/access.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/aligned_df.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/aligned_mapping.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/extensions.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/file_backing.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/index.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/merge.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/raw.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/sparse_dataset.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/storage.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/views.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_core/xarray.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/h5ad.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/read.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/specs/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/specs/lazy_methods.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/specs/registry.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/utils.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/write.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_io/zarr.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_types.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/_warnings.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/abc.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/compat/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/_dispatch_io.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/backed/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/backed/_compat.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/backed/_io.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/backed/_lazy_arrays.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/merge.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/multi_files/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/multi_files/_anncollection.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/pytorch/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/experimental/pytorch/_annloader.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/io.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/logging.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/tests/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/tests/helpers.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/types.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/typing.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/anndata/utils.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/testing/anndata/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/testing/anndata/_doctest.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/testing/anndata/_pytest.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/src/testing/anndata/py.typed +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/conftest.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/adata-comments.tsv +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/adata.csv +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/readme.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.11.4/adata.h5ad +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.11.4/adata.zarr.zip +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.11.4/readme.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.5.0/adata.h5ad +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.5.0/readme.md +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.7.0/adata.h5ad +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.7.0/adata.zarr.zip +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.7.8/adata.h5ad +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/archives/v0.7.8/adata.zarr.zip +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/excel.xlsx +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/data/umi_tools.tsv.gz +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/lazy/__init__.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/lazy/conftest.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/lazy/test_concat.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/lazy/test_read.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/lazy/test_write.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_anncollection.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_annot.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_awkward.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_backed_dense.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_backed_hdf5.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_backed_sparse.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_base.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_concatenate.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_concatenate_disk.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_dask.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_dask_view_mem.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_deprecations.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_extensions.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_get_vector.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_gpu.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_helpers.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_inplace_subset.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_backwards_compat.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_conversion.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_dispatched.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_partial.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_utils.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_io_warnings.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_layers.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_obsmvarm.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_obspvarp.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_raw.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_readwrite.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_repr.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_settings.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_structured_arrays.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_transpose.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_uns.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_utils.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_views.py +0 -0
- {anndata-0.12.8 → anndata-0.12.10}/tests/test_xarray.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anndata
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.10
|
|
4
4
|
Summary: Annotated data.
|
|
5
5
|
Project-URL: Documentation, https://anndata.readthedocs.io/
|
|
6
6
|
Project-URL: Source, https://github.com/scverse/anndata
|
|
@@ -32,7 +32,7 @@ Requires-Dist: natsort
|
|
|
32
32
|
Requires-Dist: numpy>=1.26
|
|
33
33
|
Requires-Dist: packaging>=24.2
|
|
34
34
|
Requires-Dist: pandas!=2.1.2,<3,>=2.1.0
|
|
35
|
-
Requires-Dist: scipy
|
|
35
|
+
Requires-Dist: scipy!=1.17.0,>=1.12
|
|
36
36
|
Requires-Dist: zarr!=3.0.*,>=2.18.7
|
|
37
37
|
Provides-Extra: cu11
|
|
38
38
|
Requires-Dist: cupy-cuda11x; extra == 'cu11'
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(v0.12.10)=
|
|
2
|
+
### 0.12.10 {small}`2026-02-06`
|
|
3
|
+
|
|
4
|
+
#### Miscellaneous changes
|
|
5
|
+
|
|
6
|
+
- Add {attr}`anndata.settings.copy_on_write_X` to allow for forward-compatibility with future copy-on-write behavior (release `0.13`). Currently, setting {attr}`~anndata.AnnData.X` on a view implicitly updates the object from which the view was created. {user}`ilan-gold` ({pr}`2327`)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(v0.12.9)=
|
|
2
|
+
### 0.12.9 {small}`2026-01-29`
|
|
3
|
+
|
|
4
|
+
#### Performance
|
|
5
|
+
|
|
6
|
+
- Add a `write_csr_csc_indices_with_min_possible_dtype` option to {attr}`anndata.settings` to enable downcasting of the `indices` of csr and csc matrices to a smaller dtype when writing. For example, if your csr matrix only has 30000 columns, then you can write out the `indices` of that matrix as `uint16` instead of `int64`. {user}`ilan-gold` ({pr}`2159`)
|
|
@@ -40,7 +40,7 @@ dependencies = [
|
|
|
40
40
|
"pandas >=2.1.0, !=2.1.2, <3",
|
|
41
41
|
"numpy>=1.26",
|
|
42
42
|
# https://github.com/scverse/anndata/issues/1434
|
|
43
|
-
"scipy >=1.12",
|
|
43
|
+
"scipy >=1.12,!=1.17.0",
|
|
44
44
|
"h5py>=3.8",
|
|
45
45
|
"natsort",
|
|
46
46
|
"packaging>=24.2",
|
|
@@ -163,6 +163,8 @@ filterwarnings_when_strict = [
|
|
|
163
163
|
"default:.*FixedLengthUTF32:zarr.core.dtype.common.UnstableSpecificationWarning",
|
|
164
164
|
"default:Automatic shard shape inference is experimental",
|
|
165
165
|
"default:Writing zarr v2:UserWarning",
|
|
166
|
+
# TODO: Remove in conjunction with or before https://github.com/scverse/anndata/pull/1707
|
|
167
|
+
"default:.*will obey copy-on-write semantics:FutureWarning",
|
|
166
168
|
]
|
|
167
169
|
python_files = [ "test_*.py" ]
|
|
168
170
|
testpaths = [
|
|
@@ -597,8 +597,38 @@ class AnnData(metaclass=utils.DeprecationMixinMeta): # noqa: PLW1641
|
|
|
597
597
|
# else:
|
|
598
598
|
# return X
|
|
599
599
|
|
|
600
|
+
def _handle_view_X_cow(self, value: XDataType | None):
|
|
601
|
+
if self._is_view:
|
|
602
|
+
if settings.copy_on_write_X:
|
|
603
|
+
msg = "Setting element `.X` of view, initializing view as actual."
|
|
604
|
+
warnings.warn(msg, ImplicitModificationWarning, stacklevel=2)
|
|
605
|
+
new = self._mutated_copy(X=value)
|
|
606
|
+
self._init_as_actual(new)
|
|
607
|
+
return True
|
|
608
|
+
msg = "Setting element `.X` of view of `AnnData` object will obey copy-on-write semantics in the next minor release. "
|
|
609
|
+
"In other words, this subset of your original `AnnData` will be copied-in-place and initialized with the value passed into this setter. "
|
|
610
|
+
"Set `anndata.settings.copy_on_write_X = True` to begin opting in to this behavior."
|
|
611
|
+
warnings.warn(msg, FutureWarning, stacklevel=2)
|
|
612
|
+
return False
|
|
613
|
+
|
|
600
614
|
@X.setter
|
|
601
615
|
def X(self, value: XDataType | None): # noqa: PLR0912
|
|
616
|
+
value = (
|
|
617
|
+
coerce_array(value, name="X", allow_array_like=True)
|
|
618
|
+
if value is not None
|
|
619
|
+
else None
|
|
620
|
+
)
|
|
621
|
+
can_set_direct_if_not_none = value is None or (
|
|
622
|
+
np.isscalar(value)
|
|
623
|
+
or (hasattr(value, "shape") and (self.shape == value.shape))
|
|
624
|
+
or (self.n_vars == 1 and self.n_obs == len(value))
|
|
625
|
+
or (self.n_obs == 1 and self.n_vars == len(value))
|
|
626
|
+
)
|
|
627
|
+
if not can_set_direct_if_not_none:
|
|
628
|
+
msg = f"Data matrix has wrong shape {value.shape}, need to be {self.shape}."
|
|
629
|
+
raise ValueError(msg)
|
|
630
|
+
if self._handle_view_X_cow(value):
|
|
631
|
+
return None
|
|
602
632
|
if value is None:
|
|
603
633
|
if self.isbacked:
|
|
604
634
|
msg = "Cannot currently remove data matrix from backed object."
|
|
@@ -607,7 +637,6 @@ class AnnData(metaclass=utils.DeprecationMixinMeta): # noqa: PLW1641
|
|
|
607
637
|
self._init_as_actual(self.copy())
|
|
608
638
|
self._X = None
|
|
609
639
|
return
|
|
610
|
-
value = coerce_array(value, name="X", allow_array_like=True)
|
|
611
640
|
|
|
612
641
|
# If indices are both arrays, we need to modify them
|
|
613
642
|
# so we don’t set values like coordinates
|
|
@@ -620,67 +649,51 @@ class AnnData(metaclass=utils.DeprecationMixinMeta): # noqa: PLW1641
|
|
|
620
649
|
oidx, vidx = np.ix_(self._oidx, self._vidx)
|
|
621
650
|
else:
|
|
622
651
|
oidx, vidx = self._oidx, self._vidx
|
|
623
|
-
if (
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
for idx in [oidx, vidx]
|
|
634
|
-
):
|
|
635
|
-
msg = (
|
|
636
|
-
"You are attempting to set `X` to a matrix on a view which has non-unique indices. "
|
|
637
|
-
"The resulting `adata.X` will likely not equal the value to which you set it. "
|
|
638
|
-
"To avoid this potential issue, please make a copy of the data first. "
|
|
639
|
-
"In the future, this operation will throw an error."
|
|
640
|
-
)
|
|
641
|
-
warnings.warn(msg, FutureWarning, stacklevel=1)
|
|
642
|
-
if self.shape != value.shape:
|
|
643
|
-
# For assigning vector of values to 2d array or matrix
|
|
644
|
-
# Not necessary for row of 2d array
|
|
645
|
-
value = value.reshape(self.shape)
|
|
646
|
-
if self.isbacked:
|
|
647
|
-
if self.is_view:
|
|
648
|
-
X = self.file["X"]
|
|
649
|
-
if isinstance(X, h5py.Group):
|
|
650
|
-
X = sparse_dataset(X)
|
|
651
|
-
X[oidx, vidx] = value
|
|
652
|
-
else:
|
|
653
|
-
self._set_backed("X", value)
|
|
654
|
-
elif self.is_view:
|
|
655
|
-
if sparse.issparse(self._adata_ref._X) and isinstance(
|
|
656
|
-
value, np.ndarray
|
|
657
|
-
):
|
|
658
|
-
if isinstance(self._adata_ref.X, CSArray):
|
|
659
|
-
memory_class = sparse.coo_array
|
|
660
|
-
else:
|
|
661
|
-
memory_class = sparse.coo_matrix
|
|
662
|
-
value = memory_class(value)
|
|
663
|
-
elif sparse.issparse(value) and isinstance(
|
|
664
|
-
self._adata_ref._X, np.ndarray
|
|
665
|
-
):
|
|
666
|
-
warnings.warn(
|
|
667
|
-
"Trying to set a dense array with a sparse array on a view."
|
|
668
|
-
"Densifying the sparse array."
|
|
669
|
-
"This may incur excessive memory usage",
|
|
670
|
-
stacklevel=2,
|
|
671
|
-
)
|
|
672
|
-
value = value.toarray()
|
|
673
|
-
warnings.warn(
|
|
674
|
-
"Modifying `X` on a view results in data being overridden",
|
|
675
|
-
ImplicitModificationWarning,
|
|
676
|
-
stacklevel=2,
|
|
652
|
+
if not np.isscalar(value):
|
|
653
|
+
if self.is_view and any(
|
|
654
|
+
isinstance(idx, np.ndarray) and len(np.unique(idx)) != len(idx.ravel())
|
|
655
|
+
for idx in [oidx, vidx]
|
|
656
|
+
):
|
|
657
|
+
msg = (
|
|
658
|
+
"You are attempting to set `X` to a matrix on a view which has non-unique indices. "
|
|
659
|
+
"The resulting `adata.X` will likely not equal the value to which you set it. "
|
|
660
|
+
"To avoid this potential issue, please make a copy of the data first. "
|
|
661
|
+
"In the future, this operation will throw an error."
|
|
677
662
|
)
|
|
678
|
-
|
|
663
|
+
warnings.warn(msg, FutureWarning, stacklevel=2)
|
|
664
|
+
if self.shape != value.shape:
|
|
665
|
+
# For assigning vector of values to 2d array or matrix
|
|
666
|
+
# Not necessary for row of 2d array
|
|
667
|
+
value = value.reshape(self.shape)
|
|
668
|
+
if self.isbacked:
|
|
669
|
+
if self.is_view:
|
|
670
|
+
X = self.file["X"]
|
|
671
|
+
if isinstance(X, h5py.Group):
|
|
672
|
+
msg = "Cannot write to views of sparse backed files"
|
|
673
|
+
raise NotImplementedError(msg)
|
|
674
|
+
X[oidx, vidx] = value
|
|
679
675
|
else:
|
|
680
|
-
self.
|
|
676
|
+
self._set_backed("X", value)
|
|
677
|
+
elif self.is_view:
|
|
678
|
+
if sparse.issparse(self._adata_ref._X) and isinstance(value, np.ndarray):
|
|
679
|
+
if isinstance(self._adata_ref.X, CSArray):
|
|
680
|
+
memory_class = sparse.coo_array
|
|
681
|
+
else:
|
|
682
|
+
memory_class = sparse.coo_matrix
|
|
683
|
+
value = memory_class(value)
|
|
684
|
+
elif sparse.issparse(value) and isinstance(self._adata_ref._X, np.ndarray):
|
|
685
|
+
msg = (
|
|
686
|
+
"Trying to set a dense array with a sparse array on a view. "
|
|
687
|
+
"Densifying the sparse array. "
|
|
688
|
+
"This may incur excessive memory usage"
|
|
689
|
+
)
|
|
690
|
+
warnings.warn(msg, UserWarning, stacklevel=2)
|
|
691
|
+
value = value.toarray()
|
|
692
|
+
msg = "Modifying `X` on a view results in data being overridden"
|
|
693
|
+
warnings.warn(msg, ImplicitModificationWarning, stacklevel=2)
|
|
694
|
+
self._adata_ref._X[oidx, vidx] = value
|
|
681
695
|
else:
|
|
682
|
-
|
|
683
|
-
raise ValueError(msg)
|
|
696
|
+
self._X = value
|
|
684
697
|
|
|
685
698
|
@X.deleter
|
|
686
699
|
def X(self):
|
|
@@ -1492,8 +1505,7 @@ class AnnData(metaclass=utils.DeprecationMixinMeta): # noqa: PLW1641
|
|
|
1492
1505
|
return self._mutated_copy(
|
|
1493
1506
|
X=_subset(self._adata_ref.X, (self._oidx, self._vidx)).copy()
|
|
1494
1507
|
)
|
|
1495
|
-
|
|
1496
|
-
return self._mutated_copy()
|
|
1508
|
+
return self._mutated_copy()
|
|
1497
1509
|
else:
|
|
1498
1510
|
from ..io import read_h5ad, write_h5ad
|
|
1499
1511
|
|
|
@@ -738,6 +738,24 @@ def write_sparse_compressed(
|
|
|
738
738
|
for attr_name in ["data", "indices", "indptr"]:
|
|
739
739
|
attr = getattr(value, attr_name)
|
|
740
740
|
dtype = indptr_dtype if attr_name == "indptr" else attr.dtype
|
|
741
|
+
if (
|
|
742
|
+
attr_name == "indices"
|
|
743
|
+
and settings.write_csr_csc_indices_with_min_possible_dtype
|
|
744
|
+
):
|
|
745
|
+
# np.min_scalar_type can return things like np.ulonglong which zarr doesn't understand
|
|
746
|
+
# and I find this clearer as to what the result type is i.e., unsigned or signed.
|
|
747
|
+
# For example `np.iinfo(np.uint16).max + 1` could be either `uint32` or `int32`,
|
|
748
|
+
# and there's nothing in numpy's docs disallowing this output to change.
|
|
749
|
+
if (minor_axis_size := value.shape[value.format == "csr"]) <= np.iinfo(
|
|
750
|
+
np.uint8
|
|
751
|
+
).max:
|
|
752
|
+
dtype = np.dtype("uint8")
|
|
753
|
+
elif minor_axis_size <= np.iinfo(np.uint16).max:
|
|
754
|
+
dtype = np.dtype("uint16")
|
|
755
|
+
elif minor_axis_size <= np.iinfo(np.uint32).max:
|
|
756
|
+
dtype = np.dtype("uint32")
|
|
757
|
+
elif minor_axis_size <= np.iinfo(np.uint64).max:
|
|
758
|
+
dtype = np.dtype("uint64")
|
|
741
759
|
if isinstance(f, H5Group) or is_zarr_v2():
|
|
742
760
|
g.create_dataset(
|
|
743
761
|
attr_name, data=attr, shape=attr.shape, dtype=dtype, **dataset_kwargs
|
|
@@ -503,6 +503,14 @@ settings.register(
|
|
|
503
503
|
get_from_env=check_and_get_bool,
|
|
504
504
|
)
|
|
505
505
|
|
|
506
|
+
settings.register(
|
|
507
|
+
"write_csr_csc_indices_with_min_possible_dtype",
|
|
508
|
+
default_value=False,
|
|
509
|
+
description="Write a csr or csc matrix with the minimum possible data type for `indices`, always unsigned integer.",
|
|
510
|
+
validate=validate_bool,
|
|
511
|
+
get_from_env=check_and_get_bool,
|
|
512
|
+
)
|
|
513
|
+
|
|
506
514
|
settings.register(
|
|
507
515
|
"auto_shard_zarr_v3",
|
|
508
516
|
default_value=False,
|
|
@@ -512,5 +520,18 @@ settings.register(
|
|
|
512
520
|
)
|
|
513
521
|
|
|
514
522
|
|
|
523
|
+
settings.register(
|
|
524
|
+
"copy_on_write_X",
|
|
525
|
+
default_value=False,
|
|
526
|
+
description=(
|
|
527
|
+
"Whether to copy-on-write X. "
|
|
528
|
+
"Currently `my_adata_view[subset].X = value` will write back to the original AnnData object at the `subset` location. "
|
|
529
|
+
"`X` is the only element where this behavior is implemented though."
|
|
530
|
+
),
|
|
531
|
+
validate=validate_bool,
|
|
532
|
+
get_from_env=check_and_get_bool,
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
|
|
515
536
|
##################################################################################
|
|
516
537
|
##################################################################################
|
|
@@ -42,10 +42,12 @@ class _AnnDataSettingsManager(SettingsManager):
|
|
|
42
42
|
remove_unused_categories: bool = True
|
|
43
43
|
check_uniqueness: bool = True
|
|
44
44
|
allow_write_nullable_strings: bool = False
|
|
45
|
+
copy_on_write_X: bool = False
|
|
45
46
|
zarr_write_format: Literal[2, 3] = 2
|
|
46
47
|
use_sparse_array_on_read: bool = False
|
|
47
48
|
min_rows_for_chunked_h5_copy: int = 1000
|
|
48
49
|
disallow_forward_slash_in_h5ad: bool = False
|
|
50
|
+
write_csr_csc_indices_with_min_possible_dtype: bool = False
|
|
49
51
|
auto_shard_zarr_v3: bool = False
|
|
50
52
|
|
|
51
53
|
settings: _AnnDataSettingsManager
|
|
@@ -455,6 +455,113 @@ def test_write_indptr_dtype_override(store, sparse_format):
|
|
|
455
455
|
np.testing.assert_array_equal(store["X/indptr"][...], X.indptr)
|
|
456
456
|
|
|
457
457
|
|
|
458
|
+
@pytest.mark.parametrize(
|
|
459
|
+
("num_minor_axis", "expected_dtype"),
|
|
460
|
+
[
|
|
461
|
+
pytest.param(1, np.dtype("uint8"), id="one_col-expected_uint8_on_disk"),
|
|
462
|
+
pytest.param(
|
|
463
|
+
np.iinfo(np.uint8).max,
|
|
464
|
+
np.dtype("uint8"),
|
|
465
|
+
id="max_np.uint8-matching_dtype_on_disk",
|
|
466
|
+
),
|
|
467
|
+
pytest.param(
|
|
468
|
+
np.iinfo(np.int8).max,
|
|
469
|
+
np.dtype("uint8"),
|
|
470
|
+
id="max_np.int8-uint8_on_disk",
|
|
471
|
+
),
|
|
472
|
+
pytest.param(
|
|
473
|
+
np.iinfo(np.uint16).max,
|
|
474
|
+
np.dtype("uint16"),
|
|
475
|
+
id="max_np.uint16-matching_dtype_on_disk",
|
|
476
|
+
),
|
|
477
|
+
pytest.param(
|
|
478
|
+
np.iinfo(np.int16).max,
|
|
479
|
+
np.dtype("uint16"),
|
|
480
|
+
id="max_np.int16-uint16_on_disk",
|
|
481
|
+
),
|
|
482
|
+
pytest.param(
|
|
483
|
+
np.iinfo(np.uint32).max,
|
|
484
|
+
np.dtype("uint32"),
|
|
485
|
+
id="max_np.uint32-matching_dtype_on_disk",
|
|
486
|
+
),
|
|
487
|
+
pytest.param(
|
|
488
|
+
np.iinfo(np.int32).max,
|
|
489
|
+
np.dtype("uint32"),
|
|
490
|
+
id="max_np.int32-uint32_on_disk",
|
|
491
|
+
),
|
|
492
|
+
pytest.param(
|
|
493
|
+
np.iinfo(np.uint8).max + 1,
|
|
494
|
+
np.dtype("uint16"),
|
|
495
|
+
id="max_np.uint8_plus_one_cols-expected_uint16_on_disk",
|
|
496
|
+
),
|
|
497
|
+
pytest.param(
|
|
498
|
+
np.iinfo(np.uint16).max + 1,
|
|
499
|
+
np.dtype("uint32"),
|
|
500
|
+
id="max_np.uint16_plus_one_cols-expected_uint32_on_disk",
|
|
501
|
+
),
|
|
502
|
+
pytest.param(
|
|
503
|
+
np.iinfo(np.uint32).max + 1,
|
|
504
|
+
np.dtype("uint64"),
|
|
505
|
+
id="max_np.uint32_plus_one_cols-expected_uint64_on_disk",
|
|
506
|
+
),
|
|
507
|
+
pytest.param(
|
|
508
|
+
np.iinfo(np.int64).max + 1,
|
|
509
|
+
np.dtype("uint64"),
|
|
510
|
+
id="max_np.int64_plus_one_cols-expected_uint64_on_disk",
|
|
511
|
+
marks=pytest.mark.xfail(
|
|
512
|
+
reason="scipy sparse does not support bigger than max(int64) values in indices and there is no uint128."
|
|
513
|
+
),
|
|
514
|
+
),
|
|
515
|
+
pytest.param(
|
|
516
|
+
np.iinfo(np.uint64).max + 1,
|
|
517
|
+
np.dtype("uint64"),
|
|
518
|
+
id="max_np.uint64_plus_one_cols-expected_uint64_on_disk",
|
|
519
|
+
marks=pytest.mark.xfail(
|
|
520
|
+
reason="scipy sparse does not support bigger than max(int64) values in indices and there is no uint128."
|
|
521
|
+
),
|
|
522
|
+
),
|
|
523
|
+
],
|
|
524
|
+
)
|
|
525
|
+
@pytest.mark.parametrize("format", ["csr", "csc"])
|
|
526
|
+
def test_write_indices_min(
|
|
527
|
+
store: H5Group | ZarrGroup,
|
|
528
|
+
num_minor_axis: int,
|
|
529
|
+
expected_dtype: np.dtype,
|
|
530
|
+
format: Literal["csr", "csc"],
|
|
531
|
+
):
|
|
532
|
+
minor_axis_index = np.array([num_minor_axis - 1])
|
|
533
|
+
major_axis_index = np.array([10])
|
|
534
|
+
row_cols = (
|
|
535
|
+
(minor_axis_index, major_axis_index)
|
|
536
|
+
if format == "csc"
|
|
537
|
+
else (major_axis_index, minor_axis_index)
|
|
538
|
+
)
|
|
539
|
+
shape = (num_minor_axis, 20) if format == "csc" else (20, num_minor_axis)
|
|
540
|
+
X = getattr(sparse, f"{format}_array")(
|
|
541
|
+
(np.array([10]), row_cols),
|
|
542
|
+
shape=shape,
|
|
543
|
+
)
|
|
544
|
+
assert X.nnz == 1
|
|
545
|
+
with ad.settings.override(write_csr_csc_indices_with_min_possible_dtype=True):
|
|
546
|
+
write_elem(store, "X", X)
|
|
547
|
+
|
|
548
|
+
assert store["X/indices"].dtype == expected_dtype
|
|
549
|
+
with ad.settings.override(use_sparse_array_on_read=True):
|
|
550
|
+
result = read_elem(store["X"])
|
|
551
|
+
assert_equal(result.data, X.data)
|
|
552
|
+
assert_equal(result.indices, X.indices)
|
|
553
|
+
assert_equal(result.indptr, X.indptr)
|
|
554
|
+
assert X.format == result.format
|
|
555
|
+
assert result.shape == X.shape
|
|
556
|
+
# != comparison converts to csr, which allocates a lot of memory or errors out with:
|
|
557
|
+
# ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.
|
|
558
|
+
# Because the old, very large, minor axis is now the major axis and so either it fails to create or the indptr is very big.
|
|
559
|
+
# The above tests should be enough to capture the desired equality checks so this is mostly for being extra sure.
|
|
560
|
+
# See https://github.com/scipy/scipy/issues/23826
|
|
561
|
+
if not (format == "csc" and num_minor_axis > np.iinfo(np.uint16).max + 1):
|
|
562
|
+
assert (result != X).nnz == 0
|
|
563
|
+
|
|
564
|
+
|
|
458
565
|
def test_io_spec_raw(store):
|
|
459
566
|
adata = gen_adata((3, 2), **GEN_ADATA_NO_XARRAY_ARGS)
|
|
460
567
|
adata.raw = adata.copy()
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from contextlib import nullcontext
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
import pandas as pd
|
|
7
9
|
import pytest
|
|
@@ -50,17 +52,35 @@ def test_repeat_indices_view():
|
|
|
50
52
|
|
|
51
53
|
@pytest.mark.parametrize("orig_array_type", UNLABELLED_ARRAY_TYPES)
|
|
52
54
|
@pytest.mark.parametrize("new_array_type", UNLABELLED_ARRAY_TYPES)
|
|
53
|
-
|
|
55
|
+
@pytest.mark.parametrize("copy_on_write_X", [True, False], ids=["CoW", "update"])
|
|
56
|
+
def test_setter_view(orig_array_type, new_array_type, *, copy_on_write_X: bool):
|
|
57
|
+
ad.settings.copy_on_write_X = copy_on_write_X
|
|
54
58
|
adata = gen_adata((10, 10), X_type=orig_array_type)
|
|
55
59
|
orig_X = adata.X
|
|
60
|
+
expected_X = asarray(orig_X.copy())
|
|
56
61
|
to_assign = new_array_type(np.ones((9, 9)))
|
|
57
|
-
if
|
|
58
|
-
|
|
59
|
-
pytest.xfail("Cannot set a dense array with a sparse array")
|
|
62
|
+
if not copy_on_write_X:
|
|
63
|
+
expected_X[:9, :9] = asarray(to_assign)
|
|
60
64
|
view = adata[:9, :9]
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
with (
|
|
66
|
+
pytest.warns(
|
|
67
|
+
ImplicitModificationWarning if copy_on_write_X else FutureWarning,
|
|
68
|
+
match=r"initializing view as actual"
|
|
69
|
+
if copy_on_write_X
|
|
70
|
+
else r"will obey copy-on-write semantics",
|
|
71
|
+
),
|
|
72
|
+
pytest.warns(UserWarning, match=r"Trying to set a dense array")
|
|
73
|
+
if sparse.issparse(to_assign)
|
|
74
|
+
and isinstance(orig_X, np.ndarray)
|
|
75
|
+
and not copy_on_write_X
|
|
76
|
+
else nullcontext(),
|
|
77
|
+
):
|
|
78
|
+
view.X = to_assign
|
|
79
|
+
assert_equal(view.X, to_assign)
|
|
80
|
+
assert isinstance(view.X, type(to_assign) if copy_on_write_X else type(orig_X))
|
|
81
|
+
assert_equal(adata.X, expected_X)
|
|
82
|
+
# If cow, then not a view and if not cow, it is a view
|
|
83
|
+
assert view.is_view != copy_on_write_X
|
|
64
84
|
|
|
65
85
|
|
|
66
86
|
###############################
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|