From bea8bff4af88ef86185f191933a9c18c8918bbff Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 9 Apr 2024 14:00:47 +0200 Subject: [PATCH 1/8] Move tests out of package --- .azure-pipelines.yml | 13 +------------ pyproject.toml | 13 ++++--------- {src/anndata/tests => tests}/conftest.py | 3 --- .../tests => tests/data}/adata-comments.tsv | 0 {src/anndata/tests => tests/data}/adata.csv | 0 .../tests => tests}/data/archives/readme.md | 0 .../data/archives/v0.7.0/adata.h5ad | Bin .../data/archives/v0.7.0/adata.zarr.zip | Bin .../data/archives/v0.7.8/adata.h5ad | Bin .../data/archives/v0.7.8/adata.zarr.zip | Bin {src/anndata/tests => tests}/data/excel.xlsx | Bin {src/anndata/tests => tests}/data/umi_tools.tsv.gz | Bin {src/anndata/tests => tests}/test_anncollection.py | 0 {src/anndata/tests => tests}/test_annot.py | 0 {src/anndata/tests => tests}/test_awkward.py | 0 {src/anndata/tests => tests}/test_backed_sparse.py | 0 {src/anndata/tests => tests}/test_base.py | 0 {src/anndata/tests => tests}/test_concatenate.py | 0 .../tests => tests}/test_concatenate_disk.py | 0 {src/anndata/tests => tests}/test_dask.py | 0 {src/anndata/tests => tests}/test_dask_view_mem.py | 0 {src/anndata/tests => tests}/test_deprecations.py | 0 {src/anndata/tests => tests}/test_get_vector.py | 0 {src/anndata/tests => tests}/test_gpu.py | 0 {src/anndata/tests => tests}/test_hdf5_backing.py | 0 {src/anndata/tests => tests}/test_helpers.py | 0 .../anndata/tests => tests}/test_inplace_subset.py | 0 .../tests => tests}/test_io_backwards_compat.py | 0 {src/anndata/tests => tests}/test_io_conversion.py | 0 {src/anndata/tests => tests}/test_io_dispatched.py | 0 .../anndata/tests => tests}/test_io_elementwise.py | 0 {src/anndata/tests => tests}/test_io_partial.py | 0 {src/anndata/tests => tests}/test_io_utils.py | 0 {src/anndata/tests => tests}/test_io_warnings.py | 0 {src/anndata/tests => tests}/test_layers.py | 0 {src/anndata/tests => tests}/test_obsmvarm.py | 0 {src/anndata/tests => tests}/test_obspvarp.py | 0 {src/anndata/tests => tests}/test_raw.py | 0 {src/anndata/tests => tests}/test_readwrite.py | 6 +++--- {src/anndata/tests => tests}/test_repr.py | 0 {src/anndata/tests => tests}/test_settings.py | 0 .../tests => tests}/test_structured_arrays.py | 0 {src/anndata/tests => tests}/test_transpose.py | 0 {src/anndata/tests => tests}/test_uns.py | 0 {src/anndata/tests => tests}/test_utils.py | 0 {src/anndata/tests => tests}/test_views.py | 0 {src/anndata/tests => tests}/test_x.py | 0 47 files changed, 8 insertions(+), 27 deletions(-) rename {src/anndata/tests => tests}/conftest.py (80%) rename {src/anndata/tests => tests/data}/adata-comments.tsv (100%) rename {src/anndata/tests => tests/data}/adata.csv (100%) rename {src/anndata/tests => tests}/data/archives/readme.md (100%) rename {src/anndata/tests => tests}/data/archives/v0.7.0/adata.h5ad (100%) rename {src/anndata/tests => tests}/data/archives/v0.7.0/adata.zarr.zip (100%) rename {src/anndata/tests => tests}/data/archives/v0.7.8/adata.h5ad (100%) rename {src/anndata/tests => tests}/data/archives/v0.7.8/adata.zarr.zip (100%) rename {src/anndata/tests => tests}/data/excel.xlsx (100%) rename {src/anndata/tests => tests}/data/umi_tools.tsv.gz (100%) rename {src/anndata/tests => tests}/test_anncollection.py (100%) rename {src/anndata/tests => tests}/test_annot.py (100%) rename {src/anndata/tests => tests}/test_awkward.py (100%) rename {src/anndata/tests => tests}/test_backed_sparse.py (100%) rename {src/anndata/tests => tests}/test_base.py (100%) rename {src/anndata/tests => tests}/test_concatenate.py (100%) rename {src/anndata/tests => tests}/test_concatenate_disk.py (100%) rename {src/anndata/tests => tests}/test_dask.py (100%) rename {src/anndata/tests => tests}/test_dask_view_mem.py (100%) rename {src/anndata/tests => tests}/test_deprecations.py (100%) rename {src/anndata/tests => tests}/test_get_vector.py (100%) rename {src/anndata/tests => tests}/test_gpu.py (100%) rename {src/anndata/tests => tests}/test_hdf5_backing.py (100%) rename {src/anndata/tests => tests}/test_helpers.py (100%) rename {src/anndata/tests => tests}/test_inplace_subset.py (100%) rename {src/anndata/tests => tests}/test_io_backwards_compat.py (100%) rename {src/anndata/tests => tests}/test_io_conversion.py (100%) rename {src/anndata/tests => tests}/test_io_dispatched.py (100%) rename {src/anndata/tests => tests}/test_io_elementwise.py (100%) rename {src/anndata/tests => tests}/test_io_partial.py (100%) rename {src/anndata/tests => tests}/test_io_utils.py (100%) rename {src/anndata/tests => tests}/test_io_warnings.py (100%) rename {src/anndata/tests => tests}/test_layers.py (100%) rename {src/anndata/tests => tests}/test_obsmvarm.py (100%) rename {src/anndata/tests => tests}/test_obspvarp.py (100%) rename {src/anndata/tests => tests}/test_raw.py (100%) rename {src/anndata/tests => tests}/test_readwrite.py (99%) rename {src/anndata/tests => tests}/test_repr.py (100%) rename {src/anndata/tests => tests}/test_settings.py (100%) rename {src/anndata/tests => tests}/test_structured_arrays.py (100%) rename {src/anndata/tests => tests}/test_transpose.py (100%) rename {src/anndata/tests => tests}/test_uns.py (100%) rename {src/anndata/tests => tests}/test_utils.py (100%) rename {src/anndata/tests => tests}/test_views.py (100%) rename {src/anndata/tests => tests}/test_x.py (100%) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index c3781846d..a2c99c597 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -4,8 +4,7 @@ trigger: variables: RUN_COVERAGE: no - # TODO: remove paths after moving tests to test dir: https://github.com/scverse/anndata/issues/1451 - PYTEST_ADDOPTS: --color=yes --junitxml=test-data/test-results.xml anndata ./src/anndata/tests ./docs/concatenation.rst + PYTEST_ADDOPTS: --color=yes --junitxml=test-data/test-results.xml DEPENDENCIES_VERSION: "latest" # |"pre-release" | "minimum-version" TEST_TYPE: "standard" # | "coverage" @@ -85,16 +84,6 @@ jobs: displayName: "PyTest (treat warnings as errors)" condition: eq(variables['TEST_TYPE'], 'strict-warning') - # TODO: remove: https://github.com/scverse/anndata/issues/1451 - - task: PythonScript@0 - inputs: - scriptSource: inline - script: | - import sys, xml.etree.ElementTree as ET - results = ET.parse("./test-data/test-results.xml").findall("./*/*") - sys.exit(0 if len(results) > 3000 else f"Error: only {len(results)} tests run") - displayName: "Check if enough tests ran" - - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: Cobertura diff --git a/pyproject.toml b/pyproject.toml index 0390aa505..8b1a81d30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,12 +101,6 @@ test = [ ] gpu = ["cupy"] -[tool.hatch.build] -exclude = [ - "src/anndata/tests/conftest.py", - "src/anndata/tests/test_*.py", - "src/anndata/tests/data", -] [tool.hatch.version] source = "vcs" [tool.hatch.build.hooks.vcs] @@ -125,7 +119,7 @@ exclude_also = [ [tool.pytest.ini_options] addopts = [ - # "--import-mode=importlib", # TODO: enable: https://github.com/scverse/anndata/issues/1451 + "--import-mode=importlib", "--strict-markers", "--doctest-modules", "--pyargs", @@ -146,7 +140,8 @@ filterwarnings_when_strict = [ ] python_files = "test_*.py" testpaths = [ - "anndata", # docstrings and unit tests (module name due to --pyargs) + "anndata", # docstrings (module name due to --pyargs) + "./tests", # unit tests "./docs/concatenation.rst", # further doctests ] # For some reason this effects how logging is shown when tests are run @@ -180,7 +175,7 @@ ignore = [ ] [tool.ruff.lint.per-file-ignores] # E721 comparing types, but we specifically are checking that we aren't getting subtypes (views) -"src/anndata/tests/test_readwrite.py" = ["E721"] +"tests/test_readwrite.py" = ["E721"] [tool.ruff.lint.isort] known-first-party = ["anndata"] required-imports = ["from __future__ import annotations"] diff --git a/src/anndata/tests/conftest.py b/tests/conftest.py similarity index 80% rename from src/anndata/tests/conftest.py rename to tests/conftest.py index e45bf708b..e16197cc7 100644 --- a/src/anndata/tests/conftest.py +++ b/tests/conftest.py @@ -10,9 +10,6 @@ # TODO: Should be done in pyproject.toml, see anndata/conftest.py warnings.filterwarnings("ignore", category=anndata.OldFormatWarning) -# TODO: remove once we extricated test utils and tests -collect_ignore = ["helpers.py"] - @pytest.fixture def backing_h5ad(tmp_path): diff --git a/src/anndata/tests/adata-comments.tsv b/tests/data/adata-comments.tsv similarity index 100% rename from src/anndata/tests/adata-comments.tsv rename to tests/data/adata-comments.tsv diff --git a/src/anndata/tests/adata.csv b/tests/data/adata.csv similarity index 100% rename from src/anndata/tests/adata.csv rename to tests/data/adata.csv diff --git a/src/anndata/tests/data/archives/readme.md b/tests/data/archives/readme.md similarity index 100% rename from src/anndata/tests/data/archives/readme.md rename to tests/data/archives/readme.md diff --git a/src/anndata/tests/data/archives/v0.7.0/adata.h5ad b/tests/data/archives/v0.7.0/adata.h5ad similarity index 100% rename from src/anndata/tests/data/archives/v0.7.0/adata.h5ad rename to tests/data/archives/v0.7.0/adata.h5ad diff --git a/src/anndata/tests/data/archives/v0.7.0/adata.zarr.zip b/tests/data/archives/v0.7.0/adata.zarr.zip similarity index 100% rename from src/anndata/tests/data/archives/v0.7.0/adata.zarr.zip rename to tests/data/archives/v0.7.0/adata.zarr.zip diff --git a/src/anndata/tests/data/archives/v0.7.8/adata.h5ad b/tests/data/archives/v0.7.8/adata.h5ad similarity index 100% rename from src/anndata/tests/data/archives/v0.7.8/adata.h5ad rename to tests/data/archives/v0.7.8/adata.h5ad diff --git a/src/anndata/tests/data/archives/v0.7.8/adata.zarr.zip b/tests/data/archives/v0.7.8/adata.zarr.zip similarity index 100% rename from src/anndata/tests/data/archives/v0.7.8/adata.zarr.zip rename to tests/data/archives/v0.7.8/adata.zarr.zip diff --git a/src/anndata/tests/data/excel.xlsx b/tests/data/excel.xlsx similarity index 100% rename from src/anndata/tests/data/excel.xlsx rename to tests/data/excel.xlsx diff --git a/src/anndata/tests/data/umi_tools.tsv.gz b/tests/data/umi_tools.tsv.gz similarity index 100% rename from src/anndata/tests/data/umi_tools.tsv.gz rename to tests/data/umi_tools.tsv.gz diff --git a/src/anndata/tests/test_anncollection.py b/tests/test_anncollection.py similarity index 100% rename from src/anndata/tests/test_anncollection.py rename to tests/test_anncollection.py diff --git a/src/anndata/tests/test_annot.py b/tests/test_annot.py similarity index 100% rename from src/anndata/tests/test_annot.py rename to tests/test_annot.py diff --git a/src/anndata/tests/test_awkward.py b/tests/test_awkward.py similarity index 100% rename from src/anndata/tests/test_awkward.py rename to tests/test_awkward.py diff --git a/src/anndata/tests/test_backed_sparse.py b/tests/test_backed_sparse.py similarity index 100% rename from src/anndata/tests/test_backed_sparse.py rename to tests/test_backed_sparse.py diff --git a/src/anndata/tests/test_base.py b/tests/test_base.py similarity index 100% rename from src/anndata/tests/test_base.py rename to tests/test_base.py diff --git a/src/anndata/tests/test_concatenate.py b/tests/test_concatenate.py similarity index 100% rename from src/anndata/tests/test_concatenate.py rename to tests/test_concatenate.py diff --git a/src/anndata/tests/test_concatenate_disk.py b/tests/test_concatenate_disk.py similarity index 100% rename from src/anndata/tests/test_concatenate_disk.py rename to tests/test_concatenate_disk.py diff --git a/src/anndata/tests/test_dask.py b/tests/test_dask.py similarity index 100% rename from src/anndata/tests/test_dask.py rename to tests/test_dask.py diff --git a/src/anndata/tests/test_dask_view_mem.py b/tests/test_dask_view_mem.py similarity index 100% rename from src/anndata/tests/test_dask_view_mem.py rename to tests/test_dask_view_mem.py diff --git a/src/anndata/tests/test_deprecations.py b/tests/test_deprecations.py similarity index 100% rename from src/anndata/tests/test_deprecations.py rename to tests/test_deprecations.py diff --git a/src/anndata/tests/test_get_vector.py b/tests/test_get_vector.py similarity index 100% rename from src/anndata/tests/test_get_vector.py rename to tests/test_get_vector.py diff --git a/src/anndata/tests/test_gpu.py b/tests/test_gpu.py similarity index 100% rename from src/anndata/tests/test_gpu.py rename to tests/test_gpu.py diff --git a/src/anndata/tests/test_hdf5_backing.py b/tests/test_hdf5_backing.py similarity index 100% rename from src/anndata/tests/test_hdf5_backing.py rename to tests/test_hdf5_backing.py diff --git a/src/anndata/tests/test_helpers.py b/tests/test_helpers.py similarity index 100% rename from src/anndata/tests/test_helpers.py rename to tests/test_helpers.py diff --git a/src/anndata/tests/test_inplace_subset.py b/tests/test_inplace_subset.py similarity index 100% rename from src/anndata/tests/test_inplace_subset.py rename to tests/test_inplace_subset.py diff --git a/src/anndata/tests/test_io_backwards_compat.py b/tests/test_io_backwards_compat.py similarity index 100% rename from src/anndata/tests/test_io_backwards_compat.py rename to tests/test_io_backwards_compat.py diff --git a/src/anndata/tests/test_io_conversion.py b/tests/test_io_conversion.py similarity index 100% rename from src/anndata/tests/test_io_conversion.py rename to tests/test_io_conversion.py diff --git a/src/anndata/tests/test_io_dispatched.py b/tests/test_io_dispatched.py similarity index 100% rename from src/anndata/tests/test_io_dispatched.py rename to tests/test_io_dispatched.py diff --git a/src/anndata/tests/test_io_elementwise.py b/tests/test_io_elementwise.py similarity index 100% rename from src/anndata/tests/test_io_elementwise.py rename to tests/test_io_elementwise.py diff --git a/src/anndata/tests/test_io_partial.py b/tests/test_io_partial.py similarity index 100% rename from src/anndata/tests/test_io_partial.py rename to tests/test_io_partial.py diff --git a/src/anndata/tests/test_io_utils.py b/tests/test_io_utils.py similarity index 100% rename from src/anndata/tests/test_io_utils.py rename to tests/test_io_utils.py diff --git a/src/anndata/tests/test_io_warnings.py b/tests/test_io_warnings.py similarity index 100% rename from src/anndata/tests/test_io_warnings.py rename to tests/test_io_warnings.py diff --git a/src/anndata/tests/test_layers.py b/tests/test_layers.py similarity index 100% rename from src/anndata/tests/test_layers.py rename to tests/test_layers.py diff --git a/src/anndata/tests/test_obsmvarm.py b/tests/test_obsmvarm.py similarity index 100% rename from src/anndata/tests/test_obsmvarm.py rename to tests/test_obsmvarm.py diff --git a/src/anndata/tests/test_obspvarp.py b/tests/test_obspvarp.py similarity index 100% rename from src/anndata/tests/test_obspvarp.py rename to tests/test_obspvarp.py diff --git a/src/anndata/tests/test_raw.py b/tests/test_raw.py similarity index 100% rename from src/anndata/tests/test_raw.py rename to tests/test_raw.py diff --git a/src/anndata/tests/test_readwrite.py b/tests/test_readwrite.py similarity index 99% rename from src/anndata/tests/test_readwrite.py rename to tests/test_readwrite.py index 4521936dd..fa88bf569 100644 --- a/src/anndata/tests/test_readwrite.py +++ b/tests/test_readwrite.py @@ -468,21 +468,21 @@ def test_readloom_deprecations(tmp_path): def test_read_csv(): - adata = ad.read_csv(HERE / "adata.csv") + adata = ad.read_csv(HERE / "data" / "adata.csv") assert adata.obs_names.tolist() == ["r1", "r2", "r3"] assert adata.var_names.tolist() == ["c1", "c2"] assert adata.X.tolist() == X_list def test_read_tsv_strpath(): - adata = ad.read_text(str(HERE / "adata-comments.tsv"), "\t") + adata = ad.read_text(str(HERE / "data" / "adata-comments.tsv"), "\t") assert adata.obs_names.tolist() == ["r1", "r2", "r3"] assert adata.var_names.tolist() == ["c1", "c2"] assert adata.X.tolist() == X_list def test_read_tsv_iter(): - with (HERE / "adata-comments.tsv").open() as f: + with (HERE / "data" / "adata-comments.tsv").open() as f: adata = ad.read_text(f, "\t") assert adata.obs_names.tolist() == ["r1", "r2", "r3"] assert adata.var_names.tolist() == ["c1", "c2"] diff --git a/src/anndata/tests/test_repr.py b/tests/test_repr.py similarity index 100% rename from src/anndata/tests/test_repr.py rename to tests/test_repr.py diff --git a/src/anndata/tests/test_settings.py b/tests/test_settings.py similarity index 100% rename from src/anndata/tests/test_settings.py rename to tests/test_settings.py diff --git a/src/anndata/tests/test_structured_arrays.py b/tests/test_structured_arrays.py similarity index 100% rename from src/anndata/tests/test_structured_arrays.py rename to tests/test_structured_arrays.py diff --git a/src/anndata/tests/test_transpose.py b/tests/test_transpose.py similarity index 100% rename from src/anndata/tests/test_transpose.py rename to tests/test_transpose.py diff --git a/src/anndata/tests/test_uns.py b/tests/test_uns.py similarity index 100% rename from src/anndata/tests/test_uns.py rename to tests/test_uns.py diff --git a/src/anndata/tests/test_utils.py b/tests/test_utils.py similarity index 100% rename from src/anndata/tests/test_utils.py rename to tests/test_utils.py diff --git a/src/anndata/tests/test_views.py b/tests/test_views.py similarity index 100% rename from src/anndata/tests/test_views.py rename to tests/test_views.py diff --git a/src/anndata/tests/test_x.py b/tests/test_x.py similarity index 100% rename from src/anndata/tests/test_x.py rename to tests/test_x.py From cd5b5300312dbc9f319e61fd68363a4d04617d5c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 9 Apr 2024 14:26:06 +0200 Subject: [PATCH 2/8] clean up warnings --- pyproject.toml | 6 ++---- tests/conftest.py | 6 ------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8b1a81d30..fc4e4f935 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,10 +125,8 @@ addopts = [ "--pyargs", ] filterwarnings = [ - 'ignore:Support for Awkward Arrays is currently experimental', - 'ignore:Outer joins on awkward\.Arrays', - # TODO: replace both lines above with this one once we figured out how prevent ImportPathMismatchError - # 'ignore::anndata._warnings.ExperimentalFeatureWarning', + 'ignore::anndata._warnings.ExperimentalFeatureWarning', + 'ignore::anndata.OldFormatWarning', ] # When `--strict-warnings` is used, all warnings are treated as errors, except those: filterwarnings_when_strict = [ diff --git a/tests/conftest.py b/tests/conftest.py index e16197cc7..22ec4b6bd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,15 +1,9 @@ from __future__ import annotations -import warnings - import pytest -import anndata from anndata.tests.helpers import subset_func # noqa: F401 -# TODO: Should be done in pyproject.toml, see anndata/conftest.py -warnings.filterwarnings("ignore", category=anndata.OldFormatWarning) - @pytest.fixture def backing_h5ad(tmp_path): From 909172f1f963839a1ece8969c777c46fb7f18223 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 9 Apr 2024 14:26:18 +0200 Subject: [PATCH 3/8] remove pytest_8_raises helper --- src/anndata/tests/helpers.py | 16 ---------------- tests/test_helpers.py | 29 ----------------------------- tests/test_io_elementwise.py | 7 +++---- tests/test_io_utils.py | 11 +++++------ tests/test_readwrite.py | 5 ++--- 5 files changed, 10 insertions(+), 58 deletions(-) diff --git a/src/anndata/tests/helpers.py b/src/anndata/tests/helpers.py index eb4d424be..2402ee3fa 100644 --- a/src/anndata/tests/helpers.py +++ b/src/anndata/tests/helpers.py @@ -4,7 +4,6 @@ import re import warnings from collections.abc import Collection, Mapping -from contextlib import contextmanager from functools import partial, singledispatch, wraps from string import ascii_letters @@ -641,21 +640,6 @@ def _(a): return a.map_blocks(sparse.csr_matrix) -@contextmanager -def pytest_8_raises(exc_cls, *, match: str | re.Pattern = None): - """Error handling using pytest 8's support for __notes__. - - See: https://github.com/pytest-dev/pytest/pull/11227 - - Remove once pytest 8 is out! - """ - - with pytest.raises(exc_cls) as exc_info: - yield exc_info - - check_error_or_notes_match(exc_info, match) - - def check_error_or_notes_match(e: pytest.ExceptionInfo, pattern: str | re.Pattern): """ Checks whether the printed error message or the notes contains the given pattern. diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 52f1d6cb1..a463e2e25 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -8,13 +8,11 @@ from scipy import sparse import anndata as ad -from anndata.compat import add_note from anndata.tests.helpers import ( asarray, assert_equal, gen_adata, gen_awkward, - pytest_8_raises, report_name, ) from anndata.utils import dim_len @@ -250,30 +248,3 @@ def test_assert_equal_dask_sparse_arrays(): assert_equal(x, y) assert_equal(y, x) - - -@pytest.mark.parametrize( - "error, match", - [ - (Exception("test"), "test"), - (add_note(AssertionError("foo"), "bar"), "bar"), - (add_note(add_note(AssertionError("foo"), "bar"), "baz"), "bar"), - (add_note(add_note(AssertionError("foo"), "bar"), "baz"), "baz"), - ], -) -def test_check_error_notes_success(error, match): - with pytest_8_raises(Exception, match=match): - raise error - - -@pytest.mark.parametrize( - "error, match", - [ - (Exception("test"), "foo"), - (add_note(AssertionError("foo"), "bar"), "baz"), - ], -) -def test_check_error_notes_failure(error, match): - with pytest.raises(AssertionError): - with pytest_8_raises(Exception, match=match): - raise error diff --git a/tests/test_io_elementwise.py b/tests/test_io_elementwise.py index e2999cd01..cd43d57ca 100644 --- a/tests/test_io_elementwise.py +++ b/tests/test_io_elementwise.py @@ -22,7 +22,6 @@ as_cupy_type, assert_equal, gen_adata, - pytest_8_raises, ) @@ -205,7 +204,7 @@ def test_write_io_error(store, obj): rf"No method registered for writing {type(obj)} into .*Group" ) - with pytest_8_raises(IORegistryError, match=r"while writing key '/el'") as exc_info: + with pytest.raises(IORegistryError, match=r"while writing key '/el'") as exc_info: write_elem(store, "/el", obj) msg = str(exc_info.value) @@ -310,7 +309,7 @@ def test_read_zarr_from_group(tmp_path, consolidated): def test_dataframe_column_uniqueness(store): repeated_cols = pd.DataFrame(np.ones((3, 2)), columns=["a", "a"]) - with pytest_8_raises( + with pytest.raises( ValueError, match=r"Found repeated column names: \['a'\]\. Column names must be unique\.", ): @@ -320,7 +319,7 @@ def test_dataframe_column_uniqueness(store): {"col_name": [1, 2, 3]}, index=pd.Index([1, 3, 2], name="col_name") ) - with pytest_8_raises( + with pytest.raises( ValueError, match=r"DataFrame\.index\.name \('col_name'\) is also used by a column whose values are different\.", ): diff --git a/tests/test_io_utils.py b/tests/test_io_utils.py index 803a4ad72..f50249bad 100644 --- a/tests/test_io_utils.py +++ b/tests/test_io_utils.py @@ -13,7 +13,6 @@ from anndata._io.utils import report_read_key_on_error from anndata.compat import _clean_uns from anndata.experimental import read_elem, write_elem -from anndata.tests.helpers import pytest_8_raises if TYPE_CHECKING: from collections.abc import Callable @@ -50,12 +49,12 @@ def read_attr(_): group["X"] = [1, 2, 3] group.create_group("group") - with pytest_8_raises( + with pytest.raises( NotImplementedError, match=rf"reading key 'X'.*from {path}$" ): read_attr(group["X"]) - with pytest_8_raises( + with pytest.raises( NotImplementedError, match=rf"reading key 'group'.*from {path}$" ): read_attr(group["group"]) @@ -68,7 +67,7 @@ def test_write_error_info(diskfmt, tmp_path): # Assuming we don't define a writer for tuples a = ad.AnnData(uns={"a": {"b": {"c": (1, 2, 3)}}}) - with pytest_8_raises( + with pytest.raises( IORegistryError, match=r"Error raised while writing key 'c'.*to /uns/a/b" ): write(a) @@ -108,11 +107,11 @@ class Foo: # https://stackoverflow.com/a/406408/130164 <- copilot suggested lol pattern = r"(?s)^((?!Error raised while writing key '/?a').)*$" - with pytest_8_raises(IORegistryError, match=pattern): + with pytest.raises(IORegistryError, match=pattern): write_elem(group, "/", {"a": {"b": Foo()}}) write_elem(group, "/", {"a": {"b": [1, 2, 3]}}) group["a/b"].attrs["encoding-type"] = "not a real encoding type" - with pytest_8_raises(IORegistryError, match=pattern): + with pytest.raises(IORegistryError, match=pattern): read_elem(group) diff --git a/tests/test_readwrite.py b/tests/test_readwrite.py index fa88bf569..49a0a48fb 100644 --- a/tests/test_readwrite.py +++ b/tests/test_readwrite.py @@ -23,7 +23,6 @@ as_dense_dask_array, assert_equal, gen_adata, - pytest_8_raises, ) if TYPE_CHECKING: @@ -275,7 +274,7 @@ def test_read_full_io_error(tmp_path, name, read, write): write(adata, path) with store_context(path) as store: store["obs"].attrs["encoding-type"] = "invalid" - with pytest_8_raises( + with pytest.raises( IORegistryError, match=r"raised while reading key 'obs'.*from /$", ) as exc_info: @@ -671,7 +670,7 @@ def test_write_string_types(tmp_path, diskfmt): adata.obs[b"c"] = np.zeros(3) # This should error, and tell you which key is at fault - with pytest_8_raises(TypeError, match=r"writing key 'obs'") as exc_info: + with pytest.raises(TypeError, match=r"writing key 'obs'") as exc_info: write(adata_pth) assert "b'c'" in str(exc_info.value) From ba3c054355414ed4f622e8ef9d1e4eddac5607c8 Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Thu, 25 Apr 2024 11:48:30 +0200 Subject: [PATCH 4/8] Go back to programmatic use --- pyproject.toml | 4 ++-- tests/conftest.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 764b2a23c..5a1e83283 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,8 +125,8 @@ addopts = [ "--pyargs", ] filterwarnings = [ - 'ignore::anndata._warnings.ExperimentalFeatureWarning', - 'ignore::anndata.OldFormatWarning', + # all `ignore::anndata.*` entries are in `tests/conftest.py` + # See: https://github.com/pytest-dev/pytest-cov/issues/437 ] # When `--strict-warnings` is used, all warnings are treated as errors, except those: filterwarnings_when_strict = [ diff --git a/tests/conftest.py b/tests/conftest.py index 65eff92b1..173202198 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from functools import partial import joblib @@ -10,6 +11,11 @@ import anndata as ad from anndata.tests.helpers import subset_func # noqa: F401 +# TODO: Should be done in pyproject.toml eventually +# See https://github.com/pytest-dev/pytest-cov/issues/437 +warnings.filterwarnings("ignore", category=ad.OldFormatWarning) +warnings.filterwarnings("ignore", category=ad.ImplicitModificationWarning) + @pytest.fixture def backing_h5ad(tmp_path): From e94063fea7d18ca4b99199f177e536bc5fc32368 Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Thu, 25 Apr 2024 11:50:24 +0200 Subject: [PATCH 5/8] Make failing coverage noticable --- .codecov.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 68cc92f2d..48f7a5e06 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,16 +1,16 @@ # Based on pydata/xarray codecov: - require_ci_to_pass: no + require_ci_to_pass: false coverage: status: project: default: - # Require 1% coverage, i.e., always succeed - target: 1 + # Require 80% coverage + target: 80 changes: false comment: layout: "diff, flags, files" behavior: once - require_base: no + require_base: false From dabed9a503cf344c8eb3819fdf06e4eae1125319 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 25 Apr 2024 13:55:54 +0200 Subject: [PATCH 6/8] move ignores --- conftest.py | 11 +++++++++++ tests/conftest.py | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/conftest.py b/conftest.py index 578bc71d9..8e7216015 100644 --- a/conftest.py +++ b/conftest.py @@ -18,6 +18,17 @@ from pathlib import Path +# TODO: Should be done in pyproject.toml eventually +# See https://github.com/pytest-dev/pytest-cov/issues/437 +def pytest_configure(config: pytest.Config) -> None: + config.addinivalue_line( + "filterwarnings", "ignore::anndata._warnings.OldFormatWarning" + ) + config.addinivalue_line( + "filterwarnings", "ignore::anndata._warnings.ExperimentalFeatureWarning" + ) + + @pytest.fixture(autouse=True) def _suppress_env_for_doctests(request: pytest.FixtureRequest) -> None: if isinstance(request.node, pytest.DoctestItem): diff --git a/tests/conftest.py b/tests/conftest.py index 173202198..65eff92b1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,5 @@ from __future__ import annotations -import warnings from functools import partial import joblib @@ -11,11 +10,6 @@ import anndata as ad from anndata.tests.helpers import subset_func # noqa: F401 -# TODO: Should be done in pyproject.toml eventually -# See https://github.com/pytest-dev/pytest-cov/issues/437 -warnings.filterwarnings("ignore", category=ad.OldFormatWarning) -warnings.filterwarnings("ignore", category=ad.ImplicitModificationWarning) - @pytest.fixture def backing_h5ad(tmp_path): From cdc0387c94ac37059efa59d0d4989552e578ac6c Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Thu, 25 Apr 2024 13:56:49 +0200 Subject: [PATCH 7/8] fix file reference --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5a1e83283..2d4d4e71d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,7 +125,7 @@ addopts = [ "--pyargs", ] filterwarnings = [ - # all `ignore::anndata.*` entries are in `tests/conftest.py` + # all `ignore::anndata.*` entries are in `conftest.py` # See: https://github.com/pytest-dev/pytest-cov/issues/437 ] # When `--strict-warnings` is used, all warnings are treated as errors, except those: From 1ed873f29744f179ea6164b31a6c195d63443264 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Mon, 29 Apr 2024 15:58:11 +0200 Subject: [PATCH 8/8] bump pytest --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2d4d4e71d..95afba1de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,7 +83,7 @@ doc = [ ] test = [ "loompy>=3.0.5", - "pytest>=8.0", + "pytest>=8.2", "pytest-cov>=2.10", "zarr", "matplotlib",