diff --git a/yt/testing.py b/yt/testing.py index c84e097e1e9..479a13b7c7a 100644 --- a/yt/testing.py +++ b/yt/testing.py @@ -12,6 +12,7 @@ import matplotlib import numpy as np +import pytest from more_itertools import always_iterable from numpy.random import RandomState from unyt.exceptions import UnitOperationError @@ -856,6 +857,21 @@ def expand_keywords(keywords, full=False): return list_of_kwarg_dicts +def skip_case(*, reason: str): + """ + An adapter test skipping function that should work with both test runners + (nosetest or pytest) and with any Python version. + """ + if sys.version_info >= (3, 10): + # nose isn't compatible with Python 3.10 so we can't import it here + pytest.skip(reason) + else: + # pytest.skip() isn't recognized by nosetest (but nose.SkipTest works in pytest !) + from nose import SkipTest + + raise SkipTest(reason) + + def requires_module(module): """ Decorator that takes a module name as an argument and tries to import it. @@ -864,12 +880,11 @@ def requires_module(module): being imported will not fail if the module is not installed on the testing platform. """ - from nose import SkipTest def ffalse(func): @functools.wraps(func) def false_wrapper(*args, **kwargs): - raise SkipTest + skip_case(reason=f"Missing required module {module}") return false_wrapper @@ -901,8 +916,6 @@ def requires_module_pytest(*module_names): So that it can be later renamed to `requires_module`. """ - import pytest - from yt.utilities import on_demand_imports as odi def deco(func): @@ -930,8 +943,6 @@ def inner_func(*args, **kwargs): def requires_file(req_file): - from nose import SkipTest - path = ytcfg.get("yt", "test_data_dir") def ffalse(func): @@ -939,7 +950,7 @@ def ffalse(func): def false_wrapper(*args, **kwargs): if ytcfg.get("yt", "internals", "strict_requires"): raise FileNotFoundError(req_file) - raise SkipTest + skip_case(reason=f"Missing required file {req_file}") return false_wrapper @@ -1339,7 +1350,6 @@ def requires_backend(backend): Decorated function or null function """ - import pytest def ffalse(func): # returning a lambda : None causes an error when using pytest. Having @@ -1350,8 +1360,7 @@ def ffalse(func): # exception in the xfail case for that test def skip(*args, **kwargs): msg = f"`{backend}` backend not in use, skipping: `{func.__name__}`" - print(msg, file=sys.stderr) - pytest.skip(msg) + skip_case(reason=msg) if ytcfg.get("yt", "internals", "within_pytest"): return skip @@ -1367,8 +1376,6 @@ def ftrue(func): def requires_external_executable(*names): - import pytest - def deco(func): missing = [] for name in names: diff --git a/yt/visualization/tests/test_geo_projections.py b/yt/visualization/tests/test_geo_projections.py index 9b792d3f8f8..f40ef9fe826 100644 --- a/yt/visualization/tests/test_geo_projections.py +++ b/yt/visualization/tests/test_geo_projections.py @@ -1,8 +1,6 @@ import unittest -import pytest from nose.plugins.attrib import attr -from packaging.version import Version import yt from yt.testing import ANSWER_TEST_TAG, fake_amr_ds, requires_module @@ -134,12 +132,6 @@ def test_projection_object(self): def test_nondefault_transform(self): from yt.utilities.on_demand_imports import _cartopy as cartopy - if Version(cartopy.__version__) >= Version("0.19"): - # see https://github.com/yt-project/yt/issues/3705 - pytest.skip( - "SlicePlot fails with 'ValueError: Invalid vmin or vmax' (frb is full of nans or infs)" - ) - axis = "altitude" self.ds.coordinates.data_transform[axis] = "Miller" self.slc = yt.SlicePlot(self.ds, axis, ("stream", "Density"), origin="native")