diff --git a/.github/workflows/run-test-suite.yml b/.github/workflows/run-test-suite.yml index 9a4f3537f9..64a5bc9478 100644 --- a/.github/workflows/run-test-suite.yml +++ b/.github/workflows/run-test-suite.yml @@ -24,7 +24,8 @@ jobs: matrix: # Skip older ubuntu-16.04 & macos-10.15 to save usage resource os: [ubuntu-latest, macos-latest] - python-version: [3.8, 3.9] + # Note: keep versions quoted as strings else 3.10 taken as 3.1, etc. + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] # Run on new and old(er) versions of the distros we support (Linux, Mac OS) runs-on: ${{ matrix.os }} @@ -59,7 +60,7 @@ jobs: uses: conda-incubator/setup-miniconda@v2 with: auto-update-conda: true - miniconda-version: 'latest' + miniconda-version: "latest" activate-environment: cf-latest python-version: ${{ matrix.python-version }} channels: ncas, conda-forge @@ -146,7 +147,7 @@ jobs: # passing at least for that job, avoiding useless coverage reports. uses: codecov/codecov-action@v3 if: | - matrix.os == 'ubuntu-latest' && matrix.python-version == 3.8 + matrix.os == "ubuntu-latest" && matrix.python-version == "3.9" with: file: | ${{ github.workspace }}/main/cf/test/cf_coverage_reports/coverage.xml diff --git a/.github/workflows/test-source-dist.yml b/.github/workflows/test-source-dist.yml index 630dea6385..ae18686721 100644 --- a/.github/workflows/test-source-dist.yml +++ b/.github/workflows/test-source-dist.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: [3.8] + python-version: ["3.8"] runs-on: ${{ matrix.os }} # The sequence of tasks that will be executed as part of this job: @@ -52,7 +52,7 @@ jobs: uses: conda-incubator/setup-miniconda@v2 with: auto-update-conda: true - miniconda-version: 'latest' + miniconda-version: "latest" activate-environment: cf-latest python-version: ${{ matrix.python-version }} channels: ncas, conda-forge diff --git a/cf/__init__.py b/cf/__init__.py index 7dc6d44775..27ae8680af 100644 --- a/cf/__init__.py +++ b/cf/__init__.py @@ -89,7 +89,7 @@ ) x = ", ".join(_requires) -_error0 = f"cf v{ __version__} requires the modules {x}. " +_error0 = f"cf v{__version__} requires the modules {x}. " try: import cfdm diff --git a/cf/read_write/read.py b/cf/read_write/read.py index 7d8a9da547..a7ad3f23af 100644 --- a/cf/read_write/read.py +++ b/cf/read_write/read.py @@ -990,7 +990,7 @@ def read( if info: logger.info( f"{org_len} input field{_plural(org_len)} aggregated into " - f"{n} field{ _plural(n)}" + f"{n} field{_plural(n)}" ) # pragma: no cover # ---------------------------------------------------------------- diff --git a/cf/test/test_Field.py b/cf/test/test_Field.py index 4e87546a8c..945b119277 100644 --- a/cf/test/test_Field.py +++ b/cf/test/test_Field.py @@ -14,6 +14,12 @@ try: from scipy.ndimage import convolve1d + # In some cases we don't need SciPy directly, since it is required by code + # here which uses 'convolve1d' under-the-hood. Without it installed, get: + # + # NameError: name 'convolve1d' is not defined. Did you + # mean: 'cf_convolve1d'? + SCIPY_AVAILABLE = True # not 'except ImportError' as that can hide nested errors, catch anything: except Exception: @@ -2330,6 +2336,9 @@ def test_Field_percentile(self): # TODO: add loop to check get same shape and close enough data # for every possible axis combo (see also test_Data_percentile). + @unittest.skipIf( + not SCIPY_AVAILABLE, "scipy must be installed for this test." + ) def test_Field_grad_xy(self): f = cf.example_field(0) @@ -2415,6 +2424,9 @@ def test_Field_grad_xy(self): y.dimension_coordinate("X").standard_name, "longitude" ) + @unittest.skipIf( + not SCIPY_AVAILABLE, "scipy must be installed for this test." + ) def test_Field_laplacian_xy(self): f = cf.example_field(0) diff --git a/cf/test/test_Maths.py b/cf/test/test_Maths.py index 0900692aeb..342b1ec0b6 100644 --- a/cf/test/test_Maths.py +++ b/cf/test/test_Maths.py @@ -2,12 +2,30 @@ import faulthandler import unittest + +SCIPY_AVAILABLE = False +try: + # We don't need SciPy directly in this test, it is only required by code + # here which uses 'convolve1d' under-the-hood. Without it installed, get: + # + # NameError: name 'convolve1d' is not defined. Did you + # mean: 'cf_convolve1d'? + import scipy + + SCIPY_AVAILABLE = True +# not 'except ImportError' as that can hide nested errors, catch anything: +except Exception: + pass # test with this dependency will then be skipped by unittest + faulthandler.enable() # to debug seg faults and timeouts import cf class MathTest(unittest.TestCase): + @unittest.skipIf( + not SCIPY_AVAILABLE, "scipy must be installed for this test." + ) def test_curl_xy(self): f = cf.example_field(0) @@ -97,6 +115,9 @@ def test_curl_xy(self): c.dimension_coordinate("X").standard_name, "longitude" ) + @unittest.skipIf( + not SCIPY_AVAILABLE, "scipy must be installed for this test." + ) def test_div_xy(self): f = cf.example_field(0) @@ -185,6 +206,9 @@ def test_div_xy(self): d.dimension_coordinate("X").standard_name, "longitude" ) + @unittest.skipIf( + not SCIPY_AVAILABLE, "scipy must be installed for this test." + ) def test_differential_operators(self): f = cf.example_field(0)