From c44ceb7a4a45162a8d1fb9943d45d9a9e34de673 Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Sat, 17 Oct 2026 03:28:06 +0000 Subject: [PATCH 1/3] Remove zarr.tree and the Array.compressor properties Both were deprecated in 3.0.0 and were scheduled for removal in 3.2.0 by #3325. The rest of that PR shipped in 3.2.0 through #3900-#3903; these did not, and nothing recorded a new date for them. Removed: - zarr.tree, zarr.api.synchronous.tree, zarr.api.asynchronous.tree. Use Group.tree / AsyncGroup.tree. - Array.compressor and AsyncArray.compressor. Use Array.compressors. The warning-only test for zarr.tree is gone, and the v2 compressor assertions in tests/test_v2.py now use `compressors`. The zarr.storage.default_compressor shim from the same #3325 list is left alone; #4505 removes it. --- changes/+remove-3.0-deprecations.removal.md | 4 +++ src/zarr/__init__.py | 2 -- src/zarr/api/asynchronous.py | 28 -------------------- src/zarr/api/synchronous.py | 29 --------------------- src/zarr/core/array.py | 26 ------------------ tests/test_api.py | 13 --------- tests/test_v2.py | 6 ++--- 7 files changed, 7 insertions(+), 101 deletions(-) create mode 100644 changes/+remove-3.0-deprecations.removal.md diff --git a/changes/+remove-3.0-deprecations.removal.md b/changes/+remove-3.0-deprecations.removal.md new file mode 100644 index 0000000000..9d8ce85d24 --- /dev/null +++ b/changes/+remove-3.0-deprecations.removal.md @@ -0,0 +1,4 @@ +The following have been removed, having been deprecated since Zarr-Python 3.0.0: + +- `zarr.tree`, `zarr.api.synchronous.tree` and `zarr.api.asynchronous.tree`. Use `Group.tree` / `AsyncGroup.tree` instead. +- The `Array.compressor` and `AsyncArray.compressor` properties. Use `Array.compressors` instead (for Zarr format 2 arrays, `compressors[0]` is the old `compressor`, and an empty tuple means no compressor). diff --git a/src/zarr/__init__.py b/src/zarr/__init__.py index f305245f4e..2eb8cb5597 100644 --- a/src/zarr/__init__.py +++ b/src/zarr/__init__.py @@ -30,7 +30,6 @@ save, save_array, save_group, - tree, zeros, zeros_like, ) @@ -179,7 +178,6 @@ def set_format(log_format: str) -> None: "save", "save_array", "save_group", - "tree", "zeros", "zeros_like", ] diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index 5725b3d13a..fbebca108e 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -7,7 +7,6 @@ import numpy as np import numpy.typing as npt -from typing_extensions import deprecated from zarr.abc.store import Store from zarr.core.array import ( @@ -43,7 +42,6 @@ ArrayNotFoundError, GroupNotFoundError, NodeTypeValidationError, - ZarrDeprecationWarning, ZarrRuntimeWarning, ZarrUserWarning, ) @@ -91,7 +89,6 @@ "save", "save_array", "save_group", - "tree", "zeros", "zeros_like", ] @@ -615,31 +612,6 @@ async def save_group( await asyncio.gather(*aws) -@deprecated("Use AsyncGroup.tree instead.", category=ZarrDeprecationWarning) -async def tree(grp: AsyncGroup, expand: bool | None = None, level: int | None = None) -> Any: - """Provide a rich display of the hierarchy. - - !!! warning "Deprecated" - `zarr.tree()` is deprecated since v3.0.0 and will be removed in a future release. - Use `group.tree()` instead. - - Parameters - ---------- - grp : Group - Zarr or h5py group. - expand : bool, optional - Only relevant for HTML representation. If True, tree will be fully expanded. - level : int, optional - Maximum depth to descend into hierarchy. - - Returns - ------- - TreeRepr - A pretty-printable object displaying the hierarchy. - """ - return await grp.tree(expand=expand, level=level) - - async def array(data: npt.ArrayLike | AnyArray, **kwargs: Any) -> AnyAsyncArray: """Create an array filled with `data`. diff --git a/src/zarr/api/synchronous.py b/src/zarr/api/synchronous.py index 524f719742..da6e03d943 100644 --- a/src/zarr/api/synchronous.py +++ b/src/zarr/api/synchronous.py @@ -2,15 +2,12 @@ from typing import TYPE_CHECKING, Any, Literal -from typing_extensions import deprecated - import zarr.api.asynchronous as async_api import zarr.core.array from zarr.core.array import DEFAULT_FILL_VALUE, Array, AsyncArray, CompressorLike from zarr.core.group import Group from zarr.core.sync import sync from zarr.core.sync_group import create_hierarchy -from zarr.errors import ZarrDeprecationWarning if TYPE_CHECKING: from collections.abc import Iterable @@ -69,7 +66,6 @@ "save", "save_array", "save_group", - "tree", "zeros", "zeros_like", ] @@ -382,31 +378,6 @@ def save_group( ) -@deprecated("Use Group.tree instead.", category=ZarrDeprecationWarning) -def tree(grp: Group, expand: bool | None = None, level: int | None = None) -> Any: - """Provide a rich display of the hierarchy. - - !!! warning "Deprecated" - `zarr.tree()` is deprecated since v3.0.0 and will be removed in a future release. - Use `group.tree()` instead. - - Parameters - ---------- - grp : Group - Zarr or h5py group. - expand : bool, optional - Only relevant for HTML representation. If True, tree will be fully expanded. - level : int, optional - Maximum depth to descend into hierarchy. - - Returns - ------- - TreeRepr - A pretty-printable object displaying the hierarchy. - """ - return sync(async_api.tree(grp._async_group, expand=expand, level=level)) - - # TODO: add type annotations for kwargs def array(data: npt.ArrayLike | AnyArray, **kwargs: Any) -> AnyArray: """Create an array filled with `data`. diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index 06f7338755..a7cc1d46fd 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -1004,20 +1004,6 @@ def serializer(self) -> ArrayBytesCodec | None: codec for codec in self.metadata.inner_codecs if isinstance(codec, ArrayBytesCodec) ) - @property - @deprecated("Use AsyncArray.compressors instead.", category=ZarrDeprecationWarning) - def compressor(self) -> Numcodec | None: - """ - Compressor that is applied to each chunk of the array. - - !!! warning "Deprecated" - `Array.compressor` is deprecated since v3.0.0 and will be removed in a future release. - Use [`Array.compressors`][zarr.AsyncArray.compressors] instead. - """ - if self.metadata.zarr_format == 2: - return self.metadata.compressor - raise TypeError("`compressor` is not available for Zarr format 3 arrays.") - @property def compressors(self) -> tuple[Numcodec, ...] | tuple[BytesBytesCodec, ...]: """ @@ -2297,18 +2283,6 @@ def serializer(self) -> ArrayBytesCodec | None: """ return self.async_array.serializer - @property - @deprecated("Use Array.compressors instead.", category=ZarrDeprecationWarning) - def compressor(self) -> Numcodec | None: - """ - Compressor that is applied to each chunk of the array. - - !!! warning "Deprecated" - `array.compressor` is deprecated since v3.0.0 and will be removed in a future release. - Use [`array.compressors`][zarr.Array.compressors] instead. - """ - return self.async_array.compressor - @property def compressors(self) -> tuple[Numcodec, ...] | tuple[BytesBytesCodec, ...]: """ diff --git a/tests/test_api.py b/tests/test_api.py index f874bd45b7..c69683c0c0 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -51,7 +51,6 @@ ArrayNotFoundError, ContainsArrayError, MetadataValidationError, - ZarrDeprecationWarning, ZarrUserWarning, ) from zarr.storage import MemoryStore @@ -1068,18 +1067,6 @@ def test_load_local(tmp_path: Path, path: str | None, load_read_only: bool) -> N assert np.array_equal(result, data) -def test_tree() -> None: - g1 = zarr.group() - g1.create_group("foo") - g3 = g1.create_group("bar") - g3.create_group("baz") - g5 = g3.create_group("qux") - g5.create_array("baz", shape=(100,), chunks=(10,), dtype="float64") - with pytest.warns(ZarrDeprecationWarning, match=r"Group\.tree instead\."): # noqa: PT031 - assert repr(zarr.tree(g1)) == repr(g1.tree()) - assert str(zarr.tree(g1)) == str(g1.tree()) - - # @pytest.mark.parametrize("stores_from_path", [False, True]) # @pytest.mark.parametrize( # "with_chunk_store,listable", diff --git a/tests/test_v2.py b/tests/test_v2.py index 2e04339441..97f4d9d73f 100644 --- a/tests/test_v2.py +++ b/tests/test_v2.py @@ -144,13 +144,13 @@ def test_create_array_defaults(store: Store) -> None: g = zarr.open(store, mode="w", zarr_format=2) assert isinstance(g, Group) arr = g.create_array("one", dtype="i8", shape=(1,), chunks=(1,), compressor=None) - assert arr.async_array.compressor is None + assert arr.compressors == () assert not (arr.filters) arr = g.create_array("two", dtype="i8", shape=(1,), chunks=(1,)) - assert arr.async_array.compressor is not None + assert arr.compressors != () assert not (arr.filters) arr = g.create_array("three", dtype="i8", shape=(1,), chunks=(1,), compressor=Zstd()) - assert arr.async_array.compressor is not None + assert arr.compressors != () assert not (arr.filters) with pytest.raises(ValueError): g.create_array( From bee0726e9465129138a2665c75865cd8612fc7e2 Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Sat, 17 Oct 2026 01:45:19 -0400 Subject: [PATCH 2/3] Rename +remove-3.0-deprecations.removal.md to 4521.chore.md --- changes/{+remove-3.0-deprecations.removal.md => 4521.chore.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changes/{+remove-3.0-deprecations.removal.md => 4521.chore.md} (100%) diff --git a/changes/+remove-3.0-deprecations.removal.md b/changes/4521.chore.md similarity index 100% rename from changes/+remove-3.0-deprecations.removal.md rename to changes/4521.chore.md From 8b03123e5d718d3a429bc34998b423a9a1e6533f Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Sat, 17 Oct 2026 01:46:38 -0400 Subject: [PATCH 3/3] Rename changelog entry --- changes/{4521.chore.md => 4521.removal.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changes/{4521.chore.md => 4521.removal.md} (100%) diff --git a/changes/4521.chore.md b/changes/4521.removal.md similarity index 100% rename from changes/4521.chore.md rename to changes/4521.removal.md