From 1781820332fcb208e156bb8a806a01fa1bf1a00e Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 09:28:59 -0600 Subject: [PATCH 01/15] fix test_cli, turn on zstd compression filter test. --- test/test_cli.py | 5 ++++- test/test_compression_zstd.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/test_cli.py b/test/test_cli.py index f5ad1b2eb..fe1b0cdb6 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -77,5 +77,8 @@ def test_nc4tonc3_chunk(tmp_path, chunk, monkeypatch): utils.nc4tonc3() assert convert.call_args.kwargs["nchunk"] == (10 if chunk is None else chunk) with Dataset(destination) as dataset: - assert dataset.file_format == "NETCDF3_64BIT_OFFSET" + if sys.maxsize > 2**32: + assert dataset.file_format == "NETCDF3_64BIT_OFFSET" + else: + assert dataset.file_format == "NETCDF3_64BIT" np.testing.assert_array_equal(dataset.variables["values"][:], values) diff --git a/test/test_compression_zstd.py b/test/test_compression_zstd.py index 3557d5d0c..04caa3d9d 100644 --- a/test/test_compression_zstd.py +++ b/test/test_compression_zstd.py @@ -23,7 +23,9 @@ def write_netcdf(filename,dtype='f8',complevel: CompressionLevel = 6): nc.close() -@unittest.skipIf(no_plugins or not has_zstd_filter, "zstd filter not available") +# always run zstd test unless SKIP_FILTER_TEST set, so we know if filters are installed in wheels. +unittest.skipIf(os.getenv("SKIP_FILTER_TEST"), "skipping zstd filter test") +#@unittest.skipIf(no_plugins or not has_zstd_filter, "zstd filter not available") class CompressionTestCase(unittest.TestCase): def setUp(self): self.filename1 = filename1 From 12c30e38f7522f0383f4faed33936b86cdc5e2f1 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 13:37:32 -0600 Subject: [PATCH 02/15] skip compression filter test when running with old netcdf-c that doesn't have plugins --- .github/workflows/build_old.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_old.yml b/.github/workflows/build_old.yml index 7a115b74b..3e9c11bb0 100644 --- a/.github/workflows/build_old.yml +++ b/.github/workflows/build_old.yml @@ -76,6 +76,7 @@ jobs: export PATH=${NETCDF_DIR}/bin:${PATH} python checkversion.py # serial + export SKIP_FILTER_TEST=1 cd test python run_all.py # parallel (hdf5 for netcdf4, pnetcdf for netcdf3) From 33541ce6252e7177cb622185b6c469c630bf3784 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 13:44:43 -0600 Subject: [PATCH 03/15] 2nd try to skip compression filter test --- .github/workflows/build_old.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_old.yml b/.github/workflows/build_old.yml index 3e9c11bb0..58b8f3779 100644 --- a/.github/workflows/build_old.yml +++ b/.github/workflows/build_old.yml @@ -12,6 +12,7 @@ jobs: #CC: mpicc.mpich CC: mpicc #NO_NET: 1 + SKIP_FILTER_TEST: 1 strategy: matrix: python-version: ["3.14"] @@ -76,7 +77,6 @@ jobs: export PATH=${NETCDF_DIR}/bin:${PATH} python checkversion.py # serial - export SKIP_FILTER_TEST=1 cd test python run_all.py # parallel (hdf5 for netcdf4, pnetcdf for netcdf3) From b73f003852540d04617154fa7f3e0921095b1b68 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 13:55:17 -0600 Subject: [PATCH 04/15] 3rd try --- .github/workflows/build_old.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_old.yml b/.github/workflows/build_old.yml index 58b8f3779..ad5eb2d62 100644 --- a/.github/workflows/build_old.yml +++ b/.github/workflows/build_old.yml @@ -78,7 +78,7 @@ jobs: python checkversion.py # serial cd test - python run_all.py + SKIP_FILTER_TEST=1 python run_all.py # parallel (hdf5 for netcdf4, pnetcdf for netcdf3) cd ../examples #mpirun.mpich -np 4 python mpi_example.py From d14897aac53b4cd7887e5cf03bab6c3dd0fa2f29 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 15:22:00 -0600 Subject: [PATCH 05/15] fix typo --- .github/workflows/build_old.yml | 2 +- test/test_compression_zstd.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_old.yml b/.github/workflows/build_old.yml index ad5eb2d62..58b8f3779 100644 --- a/.github/workflows/build_old.yml +++ b/.github/workflows/build_old.yml @@ -78,7 +78,7 @@ jobs: python checkversion.py # serial cd test - SKIP_FILTER_TEST=1 python run_all.py + python run_all.py # parallel (hdf5 for netcdf4, pnetcdf for netcdf3) cd ../examples #mpirun.mpich -np 4 python mpi_example.py diff --git a/test/test_compression_zstd.py b/test/test_compression_zstd.py index 04caa3d9d..11a857f4c 100644 --- a/test/test_compression_zstd.py +++ b/test/test_compression_zstd.py @@ -24,7 +24,7 @@ def write_netcdf(filename,dtype='f8',complevel: CompressionLevel = 6): # always run zstd test unless SKIP_FILTER_TEST set, so we know if filters are installed in wheels. -unittest.skipIf(os.getenv("SKIP_FILTER_TEST"), "skipping zstd filter test") +@unittest.skipIf(os.getenv("SKIP_FILTER_TEST"), "skipping zstd filter test") #@unittest.skipIf(no_plugins or not has_zstd_filter, "zstd filter not available") class CompressionTestCase(unittest.TestCase): def setUp(self): From 1190fcce19e04763a921ec8063e1366a4c4223b3 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Wed, 21 Oct 2026 15:35:30 -0600 Subject: [PATCH 06/15] skip filter plugin test on windows arm64 wheel build --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4983136bc..69ae975fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -182,7 +182,8 @@ environment = {HDF5_DIR='C:\\\\Users\\runneradmin\\micromamba\\envs\\build\\Libr [[tool.cibuildwheel.overrides]] select = "*-win_arm64" inherit.environment = "append" -environment = { HDF5_DIR = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows', netCDF4_DIR = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows', PATH = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows\\\\bin;${PATH}', NO_CDL = '1' } +# no filter plugins on windows arm64 +environment = { SKIP_FILTER_TEST=1, HDF5_DIR = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows', netCDF4_DIR = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows', PATH = 'C:\\\\vcpkg\\\\installed\\\\arm64-windows\\\\bin;${PATH}', NO_CDL = '1' } repair-wheel-command = [ "delvewheel show {wheel}", "delvewheel repair -w {dest_dir} {wheel}", From ffbabd251d113aefcf673ec5c8076770d361cf47 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 09:24:03 -0600 Subject: [PATCH 07/15] bump version number --- Changelog | 5 +++++ src/netCDF4/_netCDF4.pyx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 3791d22fc..5c87d913c 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,8 @@ + version 1.7.5.1 (tag v1.7.5.1rel) + ================================= + * make sure zstd compression filter test always runs unless specifically disabled, fix cli test so it runs on + 32-bit x86. New wheels for linux that include plugins (they were left out of the 1.7.5 release). + version 1.7.5 (tag v1.7.5rel) ============================= * remove python 3.10 support (it reaches EOL October 31, 2026). diff --git a/src/netCDF4/_netCDF4.pyx b/src/netCDF4/_netCDF4.pyx index fec74fdcc..e6ce8c324 100644 --- a/src/netCDF4/_netCDF4.pyx +++ b/src/netCDF4/_netCDF4.pyx @@ -1,4 +1,4 @@ -"""Version 1.7.5 +"""Version 1.7.5.1 ------------- # Introduction @@ -1283,7 +1283,7 @@ import sys import functools from typing import Union -__version__ = "1.7.5" +__version__ = "1.7.5.1" # Initialize numpy import posixpath From deb8d8f30d4f99e50bb3aa0e493e6010076de98b Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 12:22:01 -0600 Subject: [PATCH 08/15] fix version number check --- test/test_diskless.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_diskless.py b/test/test_diskless.py index faeba36af..d491f8367 100644 --- a/test/test_diskless.py +++ b/test/test_diskless.py @@ -1,4 +1,5 @@ import unittest, os, tempfile +from packaging.version import Version import numpy as np from numpy.random.mtrand import uniform from numpy.testing import assert_array_equal, assert_array_almost_equal @@ -17,7 +18,7 @@ @unittest.skipIf( - netCDF4.__netcdf4libversion__ < "4.2.1" + Version(netCDF4.__netcdf4libversion__) < Version('4.2.1') or netCDF4.__has_parallel4_support__ or netCDF4.__has_pnetcdf_support__, "no diskless support", From 1affae31e6e924f5c3d3de4cb34c6a8de1726d56 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 12:24:41 -0600 Subject: [PATCH 09/15] test that file exists and is not empty --- test/test_diskless.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_diskless.py b/test/test_diskless.py index d491f8367..d191406cb 100644 --- a/test/test_diskless.py +++ b/test/test_diskless.py @@ -75,7 +75,7 @@ def runTest(self): assert os.path.isfile(self.file)==False # open persisted file. # first, check that file does actually exist on disk - assert os.path.isfile(self.file2)==True + assert os.path.isfile(self.file2) and os.path.getsize(self.file2) >> 0 f = netCDF4.Dataset(self.file2) foo = f.variables['data1'] # check shape. From 5421b5dd64cda341a16ce34a326768c53cd54027 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 13:29:02 -0600 Subject: [PATCH 10/15] fix typo --- test/test_diskless.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_diskless.py b/test/test_diskless.py index d191406cb..d9e838bda 100644 --- a/test/test_diskless.py +++ b/test/test_diskless.py @@ -75,7 +75,7 @@ def runTest(self): assert os.path.isfile(self.file)==False # open persisted file. # first, check that file does actually exist on disk - assert os.path.isfile(self.file2) and os.path.getsize(self.file2) >> 0 + assert os.path.isfile(self.file2) and os.path.getsize(self.file2) > 0 f = netCDF4.Dataset(self.file2) foo = f.variables['data1'] # check shape. From 6601594b1c1a2e24c72c6ca3c25069f17f870c75 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 13:42:18 -0600 Subject: [PATCH 11/15] fix version comparisons --- src/netCDF4/_netCDF4.pyx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/netCDF4/_netCDF4.pyx b/src/netCDF4/_netCDF4.pyx index e6ce8c324..5f2f8ccbf 100644 --- a/src/netCDF4/_netCDF4.pyx +++ b/src/netCDF4/_netCDF4.pyx @@ -1493,7 +1493,9 @@ def set_alignment(threshold, alignment): __netcdf4libversion__ = getlibversion().split()[0] __hdf5libversion__ = _gethdf5libversion() -_needsworkaround_issue485 = __netcdf4libversion__ < "4.4.0" or \ +# parsed lib version for comparisons (string comparison breaks for 4.10+) +_nclibversion = Version(__netcdf4libversion__.split('-')[0]) +_needsworkaround_issue485 = _nclibversion < Version("4.4.0") or \ (__netcdf4libversion__.startswith("4.4.0") and \ "-development" in __netcdf4libversion__) @@ -1605,7 +1607,7 @@ is_native_big = numpy.dtype('>f4').byteorder == c'=' # so it will compile with versions <= 4.2. NC_DISKLESS = 0x0008 # introduced in 4.6.2 -if __netcdf4libversion__[0:5] >= "4.6.2": +if _nclibversion >= Version("4.6.2"): NC_PERSIST = 0x4000 else: # prior to 4.6.2 this flag doesn't work, so make the same as NC_DISKLESS NC_PERSIST = NC_DISKLESS @@ -4499,7 +4501,7 @@ does not do anything.""" # a fix for strided slice access using HDF5 was added # in 4.6.2. # always use nc_get_vars for strided access with OpenDAP (issue #838). - if __netcdf4libversion__ >= "4.6.2" or\ + if _nclibversion >= Version("4.6.2") or\ self._grp.filepath().startswith('http'): self._use_get_vars = True else: @@ -4574,7 +4576,7 @@ does not do anything.""" if (self._grp.path != '/'): ncdump.append('path = %s' % self._grp.path) ncdump.append('unlimited dimensions: %s' % ', '.join(unlimdims)) ncdump.append('current shape = %r' % (self.shape,)) - if __netcdf4libversion__ < '4.5.1' and\ + if _nclibversion < Version('4.5.1') and\ self._grp.file_format.startswith('NETCDF3'): # issue #908: no_fill not correct for NETCDF3 files before 4.5.1 # before 4.5.1 there was no way to turn off filling on a @@ -5267,7 +5269,7 @@ rename a `Variable` attribute named `oldname` to `newname`.""" # issue 209: don't return masked array if variable filling # is disabled. else: - if __netcdf4libversion__ < '4.5.1' and\ + if _nclibversion < Version('4.5.1') and\ self._grp.file_format.startswith('NETCDF3'): # issue #908: no_fill not correct for NETCDF3 files before 4.5.1 # before 4.5.1 there was no way to turn off filling on a From 08cd4c1390cc6ef8fa079ce6a4f64d196c6bbc65 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 16:14:47 -0600 Subject: [PATCH 12/15] fix version comparison checks in tests. --- Changelog | 2 ++ test/test_masked5.py | 3 ++- test/test_vlen.py | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 5c87d913c..a692bb7f0 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,8 @@ ================================= * make sure zstd compression filter test always runs unless specifically disabled, fix cli test so it runs on 32-bit x86. New wheels for linux that include plugins (they were left out of the 1.7.5 release). + * fix version comparison logic that was broken when using netcdf-c >= 4.10.0 - this was the cause of + issue #1515 (diskless persisted datasets are no longer persisted). version 1.7.5 (tag v1.7.5rel) ============================= diff --git a/test/test_masked5.py b/test/test_masked5.py index 22a25c6d4..2d61688fc 100755 --- a/test/test_masked5.py +++ b/test/test_masked5.py @@ -1,6 +1,7 @@ import unittest import os import tempfile +from packaging.version import Version import numpy as np from numpy import ma @@ -55,7 +56,7 @@ def test_scaled(self): # issue 730 # this part fails with netcdf 4.1.3 # a bug in vlen strings? - if __netcdf4libversion__ >= '4.4.0': + if Version(__netcdf4libversion__) >= Version('4.4.0'): assert v2[0] == 'first' assert v2[1] == '' diff --git a/test/test_vlen.py b/test/test_vlen.py index 770c7ccbb..dab37be30 100644 --- a/test/test_vlen.py +++ b/test/test_vlen.py @@ -2,6 +2,7 @@ import unittest import os import tempfile +from packaging.version import Version from netCDF4 import Dataset import numpy as np from numpy.testing import assert_array_equal @@ -163,7 +164,7 @@ class VlenAppendTestCase(unittest.TestCase): def setUp(self): import netCDF4 - if netCDF4.__netcdf4libversion__ < "4.4.1": + if Version(netCDF4.__netcdf4libversion__) < Version("4.4.1"): self.skip = True try: self.skipTest("This test requires NetCDF 4.4.1 or later.") From 8a247fb2fffe1f948b4060589deeef52f2eb4ed4 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 16:51:56 -0600 Subject: [PATCH 13/15] catch InvalidVersion caused by "-development" in netcdf-c lib version --- test/test_diskless.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/test/test_diskless.py b/test/test_diskless.py index d9e838bda..728dfdbc6 100644 --- a/test/test_diskless.py +++ b/test/test_diskless.py @@ -1,9 +1,24 @@ import unittest, os, tempfile -from packaging.version import Version +from packaging.version import Version, InvalidVersion import numpy as np from numpy.random.mtrand import uniform from numpy.testing import assert_array_equal, assert_array_almost_equal import netCDF4 +import re + +def _parse_clean_version(version_str: str) -> Version: + # Normalize "-development" or any variation like "-dev" to ".dev0" + cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) + # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) + cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) + try: + return Version(cleaned) + except InvalidVersion: + # Fallback regex to pull just the numerical digits if it's still breaking + match = re.search(r'(\d+(\.\d+)+)', version_str) + if match: + return Version(match.group(1)) + raise # rudimentary test of diskless file capability. @@ -18,7 +33,7 @@ @unittest.skipIf( - Version(netCDF4.__netcdf4libversion__) < Version('4.2.1') + _parse_clean_version(netCDF4.__netcdf4libversion__) < Version('4.2.1') or netCDF4.__has_parallel4_support__ or netCDF4.__has_pnetcdf_support__, "no diskless support", From 45e53053ccc4a4b7b74d16c0ad4f43031ebd2334 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 16:58:13 -0600 Subject: [PATCH 14/15] use _parse_clean_version --- test/test_masked5.py | 19 +++++++++++++++++-- test/test_vlen.py | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/test/test_masked5.py b/test/test_masked5.py index 2d61688fc..cff9a1b4f 100755 --- a/test/test_masked5.py +++ b/test/test_masked5.py @@ -1,13 +1,28 @@ import unittest import os import tempfile -from packaging.version import Version +import re +from packaging.version import Version, InvalidVersion import numpy as np from numpy import ma from numpy.testing import assert_array_equal from netCDF4 import Dataset, __netcdf4libversion__ +def _parse_clean_version(version_str: str) -> Version: + # Normalize "-development" or any variation like "-dev" to ".dev0" + cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) + # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) + cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) + try: + return Version(cleaned) + except InvalidVersion: + # Fallback regex to pull just the numerical digits if it's still breaking + match = re.search(r'(\d+(\.\d+)+)', version_str) + if match: + return Version(match.group(1)) + raise + # Test use of vector of missing values. class VectorMissingValues(unittest.TestCase): @@ -56,7 +71,7 @@ def test_scaled(self): # issue 730 # this part fails with netcdf 4.1.3 # a bug in vlen strings? - if Version(__netcdf4libversion__) >= Version('4.4.0'): + if _parse_clean_version(__netcdf4libversion__) >= Version('4.4.0'): assert v2[0] == 'first' assert v2[1] == '' diff --git a/test/test_vlen.py b/test/test_vlen.py index dab37be30..c0118ef7f 100644 --- a/test/test_vlen.py +++ b/test/test_vlen.py @@ -2,11 +2,26 @@ import unittest import os import tempfile -from packaging.version import Version +import re +from packaging.version import Version, InvalidVersion from netCDF4 import Dataset import numpy as np from numpy.testing import assert_array_equal +def _parse_clean_version(version_str: str) -> Version: + # Normalize "-development" or any variation like "-dev" to ".dev0" + cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) + # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) + cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) + try: + return Version(cleaned) + except InvalidVersion: + # Fallback regex to pull just the numerical digits if it's still breaking + match = re.search(r'(\d+(\.\d+)+)', version_str) + if match: + return Version(match.group(1)) + raise + FILE_NAME = tempfile.NamedTemporaryFile(suffix='.nc', delete=False).name VL_NAME = 'vlen_type' VL_BASETYPE = np.int16 @@ -164,7 +179,7 @@ class VlenAppendTestCase(unittest.TestCase): def setUp(self): import netCDF4 - if Version(netCDF4.__netcdf4libversion__) < Version("4.4.1"): + if _parse_clean_version(netCDF4.__netcdf4libversion__) < Version("4.4.1"): self.skip = True try: self.skipTest("This test requires NetCDF 4.4.1 or later.") From 2ea5c75ab8b64b5e8c8c727fcfc328c7947c1927 Mon Sep 17 00:00:00 2001 From: jswhit2 Date: Thu, 22 Oct 2026 18:15:42 -0600 Subject: [PATCH 15/15] get rid of duplicated code --- test/parse_clean_version.py | 16 ++++++++++++++++ test/test_diskless.py | 20 +++----------------- test/test_masked5.py | 20 +++----------------- test/test_vlen.py | 20 +++----------------- 4 files changed, 25 insertions(+), 51 deletions(-) create mode 100644 test/parse_clean_version.py diff --git a/test/parse_clean_version.py b/test/parse_clean_version.py new file mode 100644 index 000000000..a9f74dbe5 --- /dev/null +++ b/test/parse_clean_version.py @@ -0,0 +1,16 @@ +from packaging.version import Version, InvalidVersion +import re + +def parse_clean_version(version_str: str) -> Version: + # Normalize "-development" or any variation like "-dev" to ".dev0" + cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) + # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) + cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) + try: + return Version(cleaned) + except InvalidVersion: + # Fallback regex to pull just the numerical digits if it's still breaking + match = re.search(r'(\d+(\.\d+)+)', version_str) + if match: + return Version(match.group(1)) + raise diff --git a/test/test_diskless.py b/test/test_diskless.py index 728dfdbc6..ea1d8c40f 100644 --- a/test/test_diskless.py +++ b/test/test_diskless.py @@ -1,24 +1,10 @@ import unittest, os, tempfile -from packaging.version import Version, InvalidVersion +from packaging.version import Version +from parse_clean_version import parse_clean_version import numpy as np from numpy.random.mtrand import uniform from numpy.testing import assert_array_equal, assert_array_almost_equal import netCDF4 -import re - -def _parse_clean_version(version_str: str) -> Version: - # Normalize "-development" or any variation like "-dev" to ".dev0" - cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) - # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) - cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) - try: - return Version(cleaned) - except InvalidVersion: - # Fallback regex to pull just the numerical digits if it's still breaking - match = re.search(r'(\d+(\.\d+)+)', version_str) - if match: - return Version(match.group(1)) - raise # rudimentary test of diskless file capability. @@ -33,7 +19,7 @@ def _parse_clean_version(version_str: str) -> Version: @unittest.skipIf( - _parse_clean_version(netCDF4.__netcdf4libversion__) < Version('4.2.1') + parse_clean_version(netCDF4.__netcdf4libversion__) < Version('4.2.1') or netCDF4.__has_parallel4_support__ or netCDF4.__has_pnetcdf_support__, "no diskless support", diff --git a/test/test_masked5.py b/test/test_masked5.py index cff9a1b4f..8fb6cb872 100755 --- a/test/test_masked5.py +++ b/test/test_masked5.py @@ -1,28 +1,14 @@ import unittest import os import tempfile -import re -from packaging.version import Version, InvalidVersion +from packaging.version import Version +from parse_clean_version import parse_clean_version import numpy as np from numpy import ma from numpy.testing import assert_array_equal from netCDF4 import Dataset, __netcdf4libversion__ -def _parse_clean_version(version_str: str) -> Version: - # Normalize "-development" or any variation like "-dev" to ".dev0" - cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) - # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) - cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) - try: - return Version(cleaned) - except InvalidVersion: - # Fallback regex to pull just the numerical digits if it's still breaking - match = re.search(r'(\d+(\.\d+)+)', version_str) - if match: - return Version(match.group(1)) - raise - # Test use of vector of missing values. class VectorMissingValues(unittest.TestCase): @@ -71,7 +57,7 @@ def test_scaled(self): # issue 730 # this part fails with netcdf 4.1.3 # a bug in vlen strings? - if _parse_clean_version(__netcdf4libversion__) >= Version('4.4.0'): + if parse_clean_version(__netcdf4libversion__) >= Version('4.4.0'): assert v2[0] == 'first' assert v2[1] == '' diff --git a/test/test_vlen.py b/test/test_vlen.py index c0118ef7f..584702107 100644 --- a/test/test_vlen.py +++ b/test/test_vlen.py @@ -2,25 +2,11 @@ import unittest import os import tempfile -import re -from packaging.version import Version, InvalidVersion +from packaging.version import Version from netCDF4 import Dataset import numpy as np from numpy.testing import assert_array_equal - -def _parse_clean_version(version_str: str) -> Version: - # Normalize "-development" or any variation like "-dev" to ".dev0" - cleaned = re.sub(r'[-_.]?development', '.dev0', version_str, flags=re.IGNORECASE) - # Catch cases where it's just raw text hyphens (e.g., 1.0.0-dev -> 1.0.0.dev0) - cleaned = re.sub(r'-dev(\d*)', r'.dev\1', cleaned, flags=re.IGNORECASE) - try: - return Version(cleaned) - except InvalidVersion: - # Fallback regex to pull just the numerical digits if it's still breaking - match = re.search(r'(\d+(\.\d+)+)', version_str) - if match: - return Version(match.group(1)) - raise +from parse_clean_version import parse_clean_version FILE_NAME = tempfile.NamedTemporaryFile(suffix='.nc', delete=False).name VL_NAME = 'vlen_type' @@ -179,7 +165,7 @@ class VlenAppendTestCase(unittest.TestCase): def setUp(self): import netCDF4 - if _parse_clean_version(netCDF4.__netcdf4libversion__) < Version("4.4.1"): + if parse_clean_version(netCDF4.__netcdf4libversion__) < Version("4.4.1"): self.skip = True try: self.skipTest("This test requires NetCDF 4.4.1 or later.")