Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ jobs:
runs-on: ${{ matrix.os }}
needs: detect-ci-trigger
if: needs.detect-ci-trigger.outputs.triggered == 'false'
env:
ZARR_V3_EXPERIMENTAL_API: 1
defaults:
run:
shell: bash -l {0}
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/upstream-dev-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ jobs:
name: upstream-dev
runs-on: ubuntu-latest
needs: detect-ci-trigger
env:
ZARR_V3_EXPERIMENTAL_API: 1
if: |
always()
&& (
Expand Down
6 changes: 6 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ def pytest_collection_modifyitems(items):
item.add_marker(pytest.mark.mypy)


@pytest.fixture(autouse=True)
def set_zarr_v3_api(monkeypatch):
"""Set ZARR_V3_EXPERIMENTAL_API environment variable for all tests."""
monkeypatch.setenv("ZARR_V3_EXPERIMENTAL_API", "1")


@pytest.fixture(autouse=True)
def add_standard_imports(doctest_namespace, tmpdir):
import numpy as np
Expand Down
106 changes: 100 additions & 6 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,64 @@ def skip_if_zarr_format_2(reason: str):

ON_WINDOWS = sys.platform == "win32"
default_value = object()


def _check_compression_codec_available(codec: str | None) -> bool:
"""Check if a compression codec is available in the netCDF4 library.

Parameters
----------
codec : str or None
The compression codec name (e.g., 'zstd', 'blosc_lz', etc.)

Returns
-------
bool
True if the codec is available, False otherwise.
"""
if codec is None or codec in ("zlib", "szip"):
# These are standard and should be available
return True

if not has_netCDF4:
return False

try:
import os
import tempfile

import netCDF4

# Try to create a file with the compression to test availability
with tempfile.NamedTemporaryFile(suffix=".nc", delete=False) as tmp:
tmp_path = tmp.name

try:
nc = netCDF4.Dataset(tmp_path, "w", format="NETCDF4")
nc.createDimension("x", 10)

# Attempt to create a variable with the compression
if codec and codec.startswith("blosc"):
nc.createVariable(
"test", "f4", ("x",), compression=codec, blosc_shuffle=1
)
else:
nc.createVariable("test", "f4", ("x",), compression=codec)

nc.close()
os.unlink(tmp_path)
return True
except (RuntimeError, netCDF4.NetCDF4MissingFeatureException):
# Codec not available
if os.path.exists(tmp_path):
with contextlib.suppress(OSError):
os.unlink(tmp_path)
return False
except Exception:
# Any other error, assume codec is not available
return False


dask_array_type = array_type("dask")

if TYPE_CHECKING:
Expand Down Expand Up @@ -2263,12 +2321,48 @@ def test_setncattr_string(self) -> None:
None,
"zlib",
"szip",
"zstd",
"blosc_lz",
"blosc_lz4",
"blosc_lz4hc",
"blosc_zlib",
"blosc_zstd",
pytest.param(
"zstd",
marks=pytest.mark.xfail(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use explicit netCDF versions please? then it's easy to delete when we bump the min supported version

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this re the netCDF versions though? I can look more if you have a view that it is

my initial research suggests it's about whether the codec is on the system rather than a package version

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yuck :( this is OK then.

not _check_compression_codec_available("zstd"),
reason="zstd codec not available in netCDF4 installation",
),
),
pytest.param(
"blosc_lz",
marks=pytest.mark.xfail(
not _check_compression_codec_available("blosc_lz"),
reason="blosc_lz codec not available in netCDF4 installation",
),
),
pytest.param(
"blosc_lz4",
marks=pytest.mark.xfail(
not _check_compression_codec_available("blosc_lz4"),
reason="blosc_lz4 codec not available in netCDF4 installation",
),
),
pytest.param(
"blosc_lz4hc",
marks=pytest.mark.xfail(
not _check_compression_codec_available("blosc_lz4hc"),
reason="blosc_lz4hc codec not available in netCDF4 installation",
),
),
pytest.param(
"blosc_zlib",
marks=pytest.mark.xfail(
not _check_compression_codec_available("blosc_zlib"),
reason="blosc_zlib codec not available in netCDF4 installation",
),
),
pytest.param(
"blosc_zstd",
marks=pytest.mark.xfail(
not _check_compression_codec_available("blosc_zstd"),
reason="blosc_zstd codec not available in netCDF4 installation",
),
),
],
)
@requires_netCDF4_1_6_2_or_above
Expand Down
Loading