From 6beecdec10545ecd66731dbff103a7157df16456 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Fri, 12 Jan 2024 12:57:04 +0100 Subject: [PATCH] Fix test compatibility with Pytest 8 (#1298) --- anndata/tests/test_io_warnings.py | 21 +++++++++++++++++++-- conftest.py | 14 +++++++------- pyproject.toml | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/anndata/tests/test_io_warnings.py b/anndata/tests/test_io_warnings.py index ac704c249..f6ed3e128 100644 --- a/anndata/tests/test_io_warnings.py +++ b/anndata/tests/test_io_warnings.py @@ -1,5 +1,6 @@ from __future__ import annotations +import re import warnings from importlib.util import find_spec from pathlib import Path @@ -14,10 +15,26 @@ def test_old_format_warning_thrown(): import scanpy as sc - with pytest.warns(ad._warnings.OldFormatWarning): - pth = Path(sc.datasets.__file__).parent / "10x_pbmc68k_reduced.h5ad" + pth = Path(sc.datasets.__file__).parent / "10x_pbmc68k_reduced.h5ad" + # TODO: with Pytest 8, all this can be a + # `with pytest.warns(...), pytest.warns(...):` + with warnings.catch_warnings(record=True) as record: + warnings.simplefilter("always", ad.OldFormatWarning) + warnings.simplefilter("always", FutureWarning) ad.read_h5ad(pth) + assert any(issubclass(w.category, ad.OldFormatWarning) for w in record), [ + w.message for w in record if not issubclass(w.category, FutureWarning) + ] + assert any( + issubclass(w.category, FutureWarning) + and re.match( + r"Moving element from \.uns\['neighbors']\['distances'] to \.obsp\['distances']\.", + str(w.message), + ) + for w in record + ), [w.message for w in record if not issubclass(w.category, ad.OldFormatWarning)] + def test_old_format_warning_not_thrown(tmp_path): pth = tmp_path / "current.h5ad" diff --git a/conftest.py b/conftest.py index a8c16979e..578bc71d9 100644 --- a/conftest.py +++ b/conftest.py @@ -18,11 +18,14 @@ from pathlib import Path -doctest_marker = pytest.mark.usefixtures("doctest_env") +@pytest.fixture(autouse=True) +def _suppress_env_for_doctests(request: pytest.FixtureRequest) -> None: + if isinstance(request.node, pytest.DoctestItem): + request.getfixturevalue("_doctest_env") -@pytest.fixture -def doctest_env( +@pytest.fixture() +def _doctest_env( request: pytest.FixtureRequest, cache: pytest.Cache, tmp_path: Path ) -> Generator[None, None, None]: from scanpy import settings @@ -44,7 +47,7 @@ def doctest_env( def pytest_itemcollected(item: pytest.Item) -> None: - """Define behavior of pytest.mark.gpu and doctests.""" + """Define behavior of pytest.mark.gpu.""" from importlib.util import find_spec is_gpu = len([mark for mark in item.iter_markers(name="gpu")]) > 0 @@ -53,9 +56,6 @@ def pytest_itemcollected(item: pytest.Item) -> None: pytest.mark.skipif(not find_spec("cupy"), reason="Cupy not installed.") ) - if isinstance(item, pytest.DoctestItem): - item.add_marker(doctest_marker) - def pytest_addoption(parser: pytest.Parser) -> None: """Hook to register custom CLI options and config values""" diff --git a/pyproject.toml b/pyproject.toml index ffb275bde..3501d7667 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ doc = [ ] test = [ "loompy>=3.0.5", - "pytest >=6.0, !=8.0.0rc1", # https://github.com/pytest-dev/pytest/issues/11759 + "pytest >=6.0", "pytest-cov>=2.10", "zarr", "matplotlib",