Skip to content

Commit 11dafb9

Browse files
authored
Fix align_chunks xarray backcompat + add min version tests (#1299)
* CI: min versions test on ci * CI: use matrix * CI: simplify * include zarr in min * xarray backcompat * warnigns and mypy * try higher zarr * back to 3.0.8 * zarr versison for backend + less verbose logging * skip problematic testss * warnings that shouldn't fail us * always use correct xarray tag * asssume instead of skip * zero padding in xarray version * clarify naming
1 parent b287fc6 commit 11dafb9

File tree

5 files changed

+104
-30
lines changed

5 files changed

+104
-30
lines changed

.github/workflows/python-check.yaml

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ permissions:
1616
contents: read
1717

1818
env:
19-
PYTHON_VERSION: '3.11'
19+
PYTHON_VERSION: "3.11"
2020

2121
defaults:
2222
run:
@@ -37,6 +37,8 @@ jobs:
3737
working-directory: icechunk-python
3838
args: --release --out dist --find-interpreter
3939
sccache: true
40+
env:
41+
CARGO_TERM_QUIET: true
4042

4143
- name: Upload wheels
4244
uses: actions/upload-artifact@v4
@@ -47,13 +49,25 @@ jobs:
4749
test:
4850
runs-on: ubuntu-latest
4951
needs: [build-wheels]
52+
strategy:
53+
matrix:
54+
deps-version:
55+
- name: minimum
56+
xarray: "2025.01.2"
57+
dask: "2024.11.0"
58+
distributed: "2024.11.0"
59+
zarr: "3.0.8"
60+
- name: latest
61+
xarray: "latest-release"
62+
dask: "latest-release"
63+
distributed: "latest-release"
64+
zarr: "latest-release"
5065
steps:
5166
- uses: actions/checkout@v5
5267
- name: Stand up MinIO
5368
run: |
5469
docker compose up -d minio
5570
56-
5771
- name: Download wheels
5872
uses: actions/download-artifact@v5
5973
with:
@@ -75,7 +89,7 @@ jobs:
7589
enable-cache: true
7690
python-version: ${{ env.PYTHON_VERSION }}
7791

78-
- name: Install dependencies
92+
- name: Install dependencies - ${{ matrix.deps-version.name }}
7993
shell: bash
8094
working-directory: icechunk-python
8195
run: |
@@ -85,6 +99,15 @@ jobs:
8599
python --version
86100
WHEEL=$(ls dist/*-cp311-*.whl)
87101
uv pip install "${WHEEL}[test]"
102+
# Install specific versions based on matrix
103+
if [ "${{ matrix.deps-version.name }}" = "minimum" ]; then
104+
echo "Installing minimum versions:"
105+
uv pip install --upgrade 'xarray==${{ matrix.deps-version.xarray }}' 'dask==${{ matrix.deps-version.dask }}' 'distributed==${{ matrix.deps-version.distributed }}' 'zarr==${{ matrix.deps-version.zarr }}'
106+
else
107+
echo "Using latest versions (already installed)"
108+
fi
109+
echo "Installed package versions:"
110+
uv pip list | grep -E "(xarray|dask|distributed|zarr)"
88111
89112
# this is here instead of earlier to give minio more time to get up and running
90113
# checking and waiting only right before we need it
@@ -114,11 +137,20 @@ jobs:
114137
uses: actions/cache/save@v4
115138
with:
116139
path: icechunk-python/.hypothesis/
117-
key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }}
140+
key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }}-${{ matrix.deps-version.name }}
118141

119142
xarray-backends:
120143
runs-on: ubuntu-latest
121144
needs: [build-wheels]
145+
strategy:
146+
matrix:
147+
xarray-version:
148+
- name: minimum
149+
version: "2025.01.2"
150+
zarr: "3.0.8"
151+
- name: latest-release
152+
version: "latest-release"
153+
zarr: "latest-release"
122154
steps:
123155
- uses: actions/checkout@v5
124156
with:
@@ -129,13 +161,6 @@ jobs:
129161
run: |
130162
docker compose up -d minio
131163
132-
133-
- uses: actions/checkout@v5
134-
with:
135-
repository: "pydata/xarray"
136-
path: "xarray"
137-
fetch-depth: 0 # Fetch all history for all branches and tags.
138-
139164
- name: Download wheels
140165
uses: actions/download-artifact@v5
141166
with:
@@ -161,9 +186,39 @@ jobs:
161186
WHEEL=$(ls dist/*-cp311-*.whl)
162187
uv pip install "${WHEEL}[test]"
163188
uv pip install pytest-mypy-plugins
189+
# Install specific xarray version based on matrix
190+
if [ "${{ matrix.xarray-version.version }}" != "latest-release" ]; then
191+
echo "Installing xarray ${{ matrix.xarray-version.version }}"
192+
uv pip install --upgrade 'xarray==${{ matrix.xarray-version.version }}'
193+
fi
194+
# Install specific zarr version based on matrix
195+
if [ "${{ matrix.xarray-version.zarr }}" != "latest-release" ]; then
196+
echo "Installing zarr ${{ matrix.xarray-version.zarr }}"
197+
uv pip install --upgrade 'zarr==${{ matrix.xarray-version.zarr }}'
198+
fi
199+
echo "Installed package versions:"
200+
python -c "import xarray; import zarr; print(f'xarray: {xarray.__version__}'); print(f'zarr: {zarr.__version__}')"
201+
202+
- name: Checkout xarray at installed version
203+
shell: bash
204+
working-directory: icechunk/icechunk-python
205+
run: |
206+
set -e
207+
source .venv/bin/activate
208+
XARRAY_VERSION=$(python -c "import xarray; print(xarray.__version__)")
209+
# Convert version to tag format (e.g., 2025.1.2 -> v2025.01.2)
210+
XARRAY_TAG=$(python -c "
211+
import xarray
212+
v = xarray.__version__
213+
parts = v.split('.')
214+
# Zero-pad month to 2 digits
215+
tag = f'v{parts[0]}.{parts[1].zfill(2)}.{parts[2]}'
216+
print(tag)
217+
")
218+
echo "Checking out xarray ${XARRAY_TAG} (version ${XARRAY_VERSION})"
219+
cd ../../
220+
git clone --depth 1 --branch "${XARRAY_TAG}" https://github.com/pydata/xarray.git xarray
164221
165-
# this is here instead of earlier to give minio more time to get up and running
166-
# checking and waiting only right before we need it
167222
- name: Wait for MinIO to be ready
168223
working-directory: icechunk
169224
run: |
@@ -179,7 +234,6 @@ jobs:
179234
working-directory: icechunk/icechunk-python
180235
env:
181236
ICECHUNK_XARRAY_BACKENDS_TESTS: 1
182-
ICECHUNK_LOG: trace
183237
run: |
184238
set -e
185239
# pass xarray's pyproject.toml so that pytest can find the `flaky` fixture

icechunk-python/pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,12 @@ filterwarnings = [
144144
"error",
145145
"ignore:Jupyter is migrating its paths to use:DeprecationWarning:",
146146
"ignore:Port 8787 is already in use:UserWarning:",
147-
# TODO: this is raised for vlen-utf8, consolidated metadata, U1 dtype
147+
# TODO: this is raised for vlen-utf8, vlen-bytes, consolidated metadata, U1 dtype, S1 dtype
148148
"ignore:The codec `vlen-utf8` is currently not part in the Zarr format 3 specification.",
149+
"ignore:The codec `vlen-bytes` is currently not part in the Zarr format 3 specification.",
149150
"ignore:The dtype `<U1` is currently not part in the Zarr format 3 specification.",
151+
"ignore:The dtype `\\|S1` is currently not part in the Zarr format 3 specification.",
152+
"ignore:Consolidated metadata is currently not part in the Zarr format 3 specification.",
150153
"ignore::ResourceWarning",
151154
"ignore:Unused async fixture loop scope:pytest.PytestWarning",
152155
"ignore:.*does not have a Zarr V3 specification.*",

icechunk-python/python/icechunk/xarray.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,20 +117,26 @@ def _open_group(
117117
mode=mode, append_dim=append_dim, region=region
118118
)
119119

120-
self.xarray_store = ZarrStore.open_group(
121-
store=self.store,
122-
group=group,
123-
mode=concrete_mode,
124-
zarr_format=3,
125-
append_dim=append_dim,
126-
write_region=region,
127-
safe_chunks=self.safe_chunks,
128-
align_chunks=self.align_chunks,
129-
synchronizer=None,
130-
consolidated=False,
131-
consolidate_on_close=False,
132-
zarr_version=None,
133-
)
120+
# align_chunks was added in xarray 2025.06.0
121+
# For backwards compatibility, only pass it if supported
122+
kwargs: dict[str, Any] = {
123+
"store": self.store,
124+
"group": group,
125+
"mode": concrete_mode,
126+
"zarr_format": 3,
127+
"append_dim": append_dim,
128+
"write_region": region,
129+
"safe_chunks": self.safe_chunks,
130+
"synchronizer": None,
131+
"consolidated": False,
132+
"consolidate_on_close": False,
133+
"zarr_version": None,
134+
}
135+
136+
if Version(xr.__version__) >= Version("2025.06.0"):
137+
kwargs["align_chunks"] = self.align_chunks
138+
139+
self.xarray_store = ZarrStore.open_group(**kwargs)
134140
self.dataset = self.xarray_store._validate_and_autodetect_region(self.dataset)
135141

136142
def write_metadata(self, encoding: Mapping[Any, Any] | None = None) -> None:

icechunk-python/tests/test_zarr/test_properties.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import pytest
44
from numpy.testing import assert_array_equal
5+
from packaging.version import Version
56

67
from icechunk import IcechunkStore, Repository, in_memory_storage
78

89
pytest.importorskip("hypothesis")
9-
1010
import hypothesis.strategies as st
1111
from hypothesis import assume, given, settings
1212

13+
import zarr
1314
from zarr.testing.strategies import arrays, numpy_arrays
1415

1516

@@ -27,6 +28,11 @@ def test_roundtrip(data: st.DataObject, nparray: Any) -> None:
2728
# TODO: support size-0 arrays GH392
2829
assume(nparray.size > 0)
2930

31+
# Skip bytes, unicode string, and datetime dtypes with zarr < 3.1.0
32+
# These have codec/dtype issues that were fixed in 3.1.0's dtype refactor
33+
if Version(zarr.__version__) < Version("3.1.0"):
34+
assume(nparray.dtype.kind not in ("S", "U", "M", "m"))
35+
3036
zarray = data.draw(
3137
arrays(
3238
stores=icechunk_stores,

icechunk-python/tests/test_zarr/test_stateful.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
rule,
1616
run_state_machine_as_test,
1717
)
18+
from packaging.version import Version
1819

1920
import icechunk as ic
2021
import zarr
@@ -205,6 +206,10 @@ def add_array(
205206
array, _ = array_and_chunks
206207
# TODO: support size-0 arrays GH392
207208
assume(array.size > 0)
209+
# Skip bytes, unicode string, and datetime dtypes with zarr < 3.1.0
210+
# These have codec/dtype issues that were fixed in 3.1.0's dtype refactor
211+
if Version(zarr.__version__) < Version("3.1.0"):
212+
assume(array.dtype.kind not in ("S", "U", "M", "m"))
208213
super().add_array(data, name, array_and_chunks)
209214

210215
@precondition(lambda self: bool(self.all_groups))

0 commit comments

Comments
 (0)