diff --git a/cf/test/test_Field.py b/cf/test/test_Field.py index 881ddbb3eb..92a72ff8a8 100644 --- a/cf/test/test_Field.py +++ b/cf/test/test_Field.py @@ -1,6 +1,7 @@ import atexit import datetime import faulthandler +from importlib.util import find_spec import itertools import os import re @@ -1152,6 +1153,8 @@ def test_Field_insert_dimension(self): with self.assertRaises(ValueError): f.insert_dimension(1, "qwerty") + @unittest.skipUnless( + find_spec("matplotlib"), "matplotlib required but not installed") def test_Field_indices(self): f = cf.read(self.filename)[0] diff --git a/cf/test/test_RegridOperator.py b/cf/test/test_RegridOperator.py index dae6be8ce8..d92bf9b554 100644 --- a/cf/test/test_RegridOperator.py +++ b/cf/test/test_RegridOperator.py @@ -1,5 +1,6 @@ import datetime import faulthandler +from importlib.util import find_spec import unittest faulthandler.enable() # to debug seg faults and timeouts @@ -7,11 +8,23 @@ import cf +# ESMF renamed its Python module to `esmpy` at ESMF version 8.4.0. Allow +# either for now for backwards compatibility. +esmpy_imported = False +# Note: here only need esmpy for cf under-the-hood code, not in test +# directly, so no need to actually import esmpy, just test it is there. +if find_spec("esmpy") or find_spec("ESMF"): + esmpy_imported = True + + class RegridOperatorTest(unittest.TestCase): - src = cf.example_field(0) - dst = cf.example_field(1) - r = src.regrids(dst, "linear", return_operator=True) + def setUp(self): + src = cf.example_field(0) + dst = cf.example_field(1) + self.r = src.regrids(dst, "linear", return_operator=True) + + @unittest.skipUnless(esmpy_imported, "Requires esmpy/ESMF package.") def test_RegridOperator_attributes(self): self.assertEqual(self.r.coord_sys, "spherical") self.assertEqual(self.r.method, "linear") @@ -39,6 +52,7 @@ def test_RegridOperator_attributes(self): self.assertIsNone(self.r.dst_z) self.assertFalse(self.r.ln_z) + @unittest.skipUnless(esmpy_imported, "Requires esmpy/ESMF package.") def test_RegridOperator_copy(self): self.assertIsInstance(self.r.copy(), self.r.__class__) diff --git a/cf/test/test_read_write.py b/cf/test/test_read_write.py index 82e3e919e8..2810c335ed 100644 --- a/cf/test/test_read_write.py +++ b/cf/test/test_read_write.py @@ -4,6 +4,7 @@ import inspect import os import shutil +import shutil import subprocess import tempfile import unittest @@ -642,6 +643,8 @@ def test_read_write_unlimited(self): self.assertTrue(domain_axes["domainaxis0"].nc_is_unlimited()) self.assertTrue(domain_axes["domainaxis2"].nc_is_unlimited()) + @unittest.skipUnless( + shutil.which("ncdump"), "ncdump required - install nco") def test_read_CDL(self): subprocess.run( " ".join(["ncdump", self.filename, ">", tmpfile]), @@ -703,6 +706,8 @@ def test_read_CDL(self): with self.assertRaises(Exception): cf.read("test_read_write.py") + @unittest.skipUnless( + shutil.which("ncdump"), "ncdump required - install nco") def test_read_cdl_string(self): """Test the cf.read 'cdl_string' keyword.""" f = cf.read("example_field_0.nc")[0] @@ -876,6 +881,8 @@ def test_read_url(self): f = cf.read(remote) self.assertEqual(len(f), 1) + @unittest.skipUnless( + shutil.which("ncdump"), "ncdump required - install nco") def test_read_dataset_type(self): """Test the cf.read 'dataset_type' keyword.""" # netCDF dataset diff --git a/cf/test/test_regrid_featureType.py b/cf/test/test_regrid_featureType.py index 198b44dd97..3a1967f3d5 100644 --- a/cf/test/test_regrid_featureType.py +++ b/cf/test/test_regrid_featureType.py @@ -36,11 +36,6 @@ atol = 2e-12 rtol = 0 -meshloc = { - "face": esmpy.MeshLoc.ELEMENT, - "node": esmpy.MeshLoc.NODE, -} - def esmpy_regrid(coord_sys, method, src, dst, **kwargs): """Helper function that regrids one dimension of Field data using @@ -53,6 +48,11 @@ def esmpy_regrid(coord_sys, method, src, dst, **kwargs): Regridded numpy masked array. """ + meshloc = { + "face": esmpy.MeshLoc.ELEMENT, + "node": esmpy.MeshLoc.NODE, + } + esmpy_regrid = cf.regrid.regrid( coord_sys, src, diff --git a/cf/test/test_regrid_mesh.py b/cf/test/test_regrid_mesh.py index 3095640135..39e29f26fe 100644 --- a/cf/test/test_regrid_mesh.py +++ b/cf/test/test_regrid_mesh.py @@ -39,11 +39,6 @@ atol = 2e-12 rtol = 0 -meshloc = { - "face": esmpy.MeshLoc.ELEMENT, - "node": esmpy.MeshLoc.NODE, -} - def esmpy_regrid(coord_sys, method, src, dst, **kwargs): """Helper function that regrids one dimension of Field data using @@ -56,6 +51,11 @@ def esmpy_regrid(coord_sys, method, src, dst, **kwargs): Regridded numpy masked array. """ + meshloc = { + "face": esmpy.MeshLoc.ELEMENT, + "node": esmpy.MeshLoc.NODE, + } + esmpy_regrid = cf.regrid.regrid( coord_sys, src, diff --git a/cf/test/test_style.py b/cf/test/test_style.py index 13ab4b45ec..907cfd892b 100644 --- a/cf/test/test_style.py +++ b/cf/test/test_style.py @@ -1,10 +1,9 @@ import datetime import faulthandler +from importlib.util import find_spec import os import unittest -import pycodestyle - faulthandler.enable() # to debug seg faults and timeouts import cf @@ -31,7 +30,11 @@ def setUp(self): for path in non_cf_python_files ] + @unittest.skipUnless( + find_spec("pycodestyle"), "pycodestyle required but not installed") def test_pep8_compliance(self): + import pycodestyle + pep8_check = pycodestyle.StyleGuide() # Directories to skip in the recursive walk of the directory: