From eaa353f9c04f8172cd4cf1766e693a3ace07cfaf Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Sat, 17 Oct 2026 02:58:16 +0000 Subject: [PATCH 1/2] Deprecate the ignored Zarr-Python 2 keyword arguments `synchronizer`, `chunk_store`, `cache_metadata`, `cache_attrs`, `object_codec`, `read_only` and `meta_array` are accepted by `create`, `group` and `open_group` (and by everything that wraps them, such as `zeros`) but have never done anything in Zarr-Python 3. Passing one used to emit a `ZarrRuntimeWarning` saying "not yet implemented", which read as a promise to implement it. Emit a `ZarrDeprecationWarning` instead, saying the argument is ignored and will be removed in a release after April 2027, and say the same in the docstrings and the v3 migration guide. Calls that do not pass these arguments are unaffected. First step of the plan for #3976. --- changes/3976.removal.md | 1 + docs/user-guide/v3_migration.md | 6 ++-- src/zarr/api/asynchronous.py | 61 ++++++++++++++------------------- src/zarr/api/synchronous.py | 44 ++++++++---------------- tests/test_api.py | 24 +++++++++++-- 5 files changed, 66 insertions(+), 70 deletions(-) create mode 100644 changes/3976.removal.md diff --git a/changes/3976.removal.md b/changes/3976.removal.md new file mode 100644 index 0000000000..b4e5a439f0 --- /dev/null +++ b/changes/3976.removal.md @@ -0,0 +1 @@ +The Zarr-Python 2 keyword arguments `synchronizer`, `chunk_store`, `cache_metadata`, `cache_attrs`, `object_codec`, `read_only` and `meta_array` accepted by `zarr.create`, `zarr.group` and `zarr.open_group` (and the functions that wrap them, such as `zarr.zeros`) have never had any effect in Zarr-Python 3. Passing one of them now emits a `ZarrDeprecationWarning` instead of a "not yet implemented" `ZarrRuntimeWarning`. They will be removed in a release after April 2027. Calls that do not pass these arguments are unaffected. diff --git a/docs/user-guide/v3_migration.md b/docs/user-guide/v3_migration.md index 0e65649650..7b15b28a89 100644 --- a/docs/user-guide/v3_migration.md +++ b/docs/user-guide/v3_migration.md @@ -231,9 +231,9 @@ The following functions / methods have not been ported to Zarr-Python 3: - `zarr.copy_all` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407)) - `zarr.copy_store` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407)) -The following features (corresponding to function arguments to functions in - `zarr`) have not been ported to Zarr-Python 3. Using these features - will raise a warning or a `NotImplementedError`: +The following function arguments from Zarr-Python 2 are accepted but ignored by + Zarr-Python 3. Passing them emits a `ZarrDeprecationWarning`, and they will be + removed in a release after April 2027: - `cache_attrs` - `cache_metadata` diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index 5725b3d13a..cd460d9562 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -44,7 +44,6 @@ GroupNotFoundError, NodeTypeValidationError, ZarrDeprecationWarning, - ZarrRuntimeWarning, ZarrUserWarning, ) from zarr.storage import StorePath @@ -109,9 +108,11 @@ def _infer_overwrite(mode: AccessModeLiteral) -> bool: return mode in _OVERWRITE_MODES -def _warn_unimplemented_kwargs(kwargs: dict[str, Any]) -> None: +def _warn_ignored_kwargs(kwargs: dict[str, Any]) -> None: """ - Emit a "not yet implemented" warning for each provided keyword argument that is not None. + Emit a deprecation warning for each provided keyword argument that is not None. + + These are Zarr-Python 2 keyword arguments that have no effect in Zarr-Python 3. `kwargs` maps a keyword argument name to its supplied value. The `stacklevel` is chosen so the warning points at the caller of the public API function (the same location as an @@ -119,7 +120,11 @@ def _warn_unimplemented_kwargs(kwargs: dict[str, Any]) -> None: """ for name, value in kwargs.items(): if value is not None: - warnings.warn(f"{name} is not yet implemented", ZarrRuntimeWarning, stacklevel=3) + warnings.warn( + f"{name} is ignored, and will be removed in a release after April 2027", + ZarrDeprecationWarning, + stacklevel=3, + ) def _get_shape_chunks(a: ArrayLike | Any) -> tuple[tuple[int, ...] | None, tuple[int, ...] | None]: @@ -717,18 +722,15 @@ async def group( If True, delete any pre-existing data in `store` at `path` before creating the group. chunk_store : StoreLike or None, default=None - Separate storage for chunks. Not implemented. + Ignored. Deprecated and will be removed in a release after April 2027. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. path : str, optional Group path within store. meta_array : array-like, optional - An array instance to use for determining arrays to create and return - to users. Use `numpy.empty(())` by default. + Ignored. Deprecated and will be removed in a release after April 2027. zarr_format : {2, 3, None}, optional The zarr format to use when saving. storage_options : dict @@ -840,23 +842,18 @@ async def open_group( (fail if exists). On a store that cannot delete keys, 'w' raises an error instead of replacing an existing node. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. path : str, optional Group path within store. chunk_store : StoreLike or None, default=None - Separate storage for chunks. See the - [storage documentation in the user guide][user-guide-store-like] - for a description of all valid StoreLike values. + Ignored. Deprecated and will be removed in a release after April 2027. storage_options : dict If using an fsspec URL to create the store, these will be passed to the backend implementation. Ignored otherwise. meta_array : array-like, optional - An array instance to use for determining arrays to create and return - to users. Use `numpy.empty(())` by default. + Ignored. Deprecated and will be removed in a release after April 2027. attributes : dict A dictionary of JSON-serializable values with user-defined attributes. use_consolidated : bool or str, default None @@ -882,7 +879,7 @@ async def open_group( The new group. """ - _warn_unimplemented_kwargs( + _warn_ignored_kwargs( { "cache_attrs": cache_attrs, "synchronizer": synchronizer, @@ -986,15 +983,14 @@ async def create( [storage documentation in the user guide][user-guide-store-like] for a description of all valid StoreLike values. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. overwrite : bool, optional If True, delete all pre-existing data in `store` at `path` before creating the array. path : str, optional Path under which array is stored. chunk_store : StoreLike or None, default=None - Separate storage for chunks. If not provided, `store` will be used - for storage of both chunks and metadata. + Ignored. Deprecated and will be removed in a release after April 2027. filters : Iterable[Codec] | Literal["auto"], optional Iterable of filters to apply to each chunk of the array, in order, before serializing that chunk to bytes. @@ -1015,18 +1011,13 @@ async def create( To create an array with no filters, provide an empty iterable or the value `None`. cache_metadata : bool, optional - If True, array configuration metadata will be cached for the - lifetime of the object. If False, array metadata will be reloaded - prior to all data access and modification operations (may incur - overhead depending on storage and data access pattern). + Ignored. Deprecated and will be removed in a release after April 2027. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. read_only : bool, optional - True if array should be protected against modification. + Ignored. Deprecated and will be removed in a release after April 2027. object_codec : Codec, optional - A codec to encode object arrays, only needed if dtype=object. + Ignored. Deprecated and will be removed in a release after April 2027. dimension_separator : {'.', '/'}, optional Separator placed between the dimensions of a chunk. Zarr format 2 only. Zarr format 3 arrays should use `chunk_key_encoding` instead. @@ -1043,7 +1034,7 @@ async def create( which instructs Zarr to choose the default Zarr format value defined in the runtime configuration. meta_array : array-like, optional - Not implemented. + Ignored. Deprecated and will be removed in a release after April 2027. attributes : dict[str, JSON], optional A dictionary of user attributes to store with the array. chunk_shape : ChunksLike, optional @@ -1101,7 +1092,7 @@ async def create( if zarr_format is None: zarr_format = _default_zarr_format() - _warn_unimplemented_kwargs( + _warn_ignored_kwargs( { "synchronizer": synchronizer, "chunk_store": chunk_store, diff --git a/src/zarr/api/synchronous.py b/src/zarr/api/synchronous.py index 524f719742..70c1b84d03 100644 --- a/src/zarr/api/synchronous.py +++ b/src/zarr/api/synchronous.py @@ -452,18 +452,15 @@ def group( If True, delete any pre-existing data in `store` at `path` before creating the group. chunk_store : StoreLike or None, default=None - Separate storage for chunks. Not implemented. + Ignored. Deprecated and will be removed in a release after April 2027. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. path : str, optional Group path within store. meta_array : array-like, optional - An array instance to use for determining arrays to create and return - to users. Use `numpy.empty(())` by default. + Ignored. Deprecated and will be removed in a release after April 2027. zarr_format : {2, 3, None}, optional The zarr format to use when saving. storage_options : dict @@ -522,23 +519,18 @@ def open_group( (fail if exists). On a store that cannot delete keys, 'w' raises an error instead of replacing an existing node. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. path : str, optional Group path within store. chunk_store : StoreLike or None, default=None - Separate storage for chunks. See the - [storage documentation in the user guide][user-guide-store-like] - for a description of all valid StoreLike values. + Ignored. Deprecated and will be removed in a release after April 2027. storage_options : dict If using an fsspec URL to create the store, these will be passed to the backend implementation. Ignored otherwise. meta_array : array-like, optional - An array instance to use for determining arrays to create and return - to users. Use `numpy.empty(())` by default. + Ignored. Deprecated and will be removed in a release after April 2027. attributes : dict A dictionary of JSON-serializable values with user-defined attributes. use_consolidated : bool or str, default None @@ -703,15 +695,14 @@ def create( [storage documentation in the user guide][user-guide-store-like] for a description of all valid StoreLike values. synchronizer : object, optional - Array synchronizer. + Ignored. Deprecated and will be removed in a release after April 2027. overwrite : bool, optional If True, delete all pre-existing data in `store` at `path` before creating the array. path : str, optional Path under which array is stored. chunk_store : StoreLike or None, default=None - Separate storage for chunks. If not provided, `store` will be used - for storage of both chunks and metadata. + Ignored. Deprecated and will be removed in a release after April 2027. filters : Iterable[Codec] | Literal["auto"], optional Iterable of filters to apply to each chunk of the array, in order, before serializing that chunk to bytes. @@ -732,18 +723,13 @@ def create( To create an array with no filters, provide an empty iterable or the value `None`. cache_metadata : bool, optional - If True, array configuration metadata will be cached for the - lifetime of the object. If False, array metadata will be reloaded - prior to all data access and modification operations (may incur - overhead depending on storage and data access pattern). + Ignored. Deprecated and will be removed in a release after April 2027. cache_attrs : bool, optional - If True (default), user attributes will be cached for attribute read - operations. If False, user attributes are reloaded from the store prior - to all attribute read operations. + Ignored. Deprecated and will be removed in a release after April 2027. read_only : bool, optional - True if array should be protected against modification. + Ignored. Deprecated and will be removed in a release after April 2027. object_codec : Codec, optional - A codec to encode object arrays, only needed if dtype=object. + Ignored. Deprecated and will be removed in a release after April 2027. dimension_separator : {'.', '/'}, optional Separator placed between the dimensions of a chunk. Zarr format 2 only. Zarr format 3 arrays should use `chunk_key_encoding` instead. @@ -760,7 +746,7 @@ def create( which instructs Zarr to choose the default Zarr format value defined in the runtime configuration. meta_array : array-like, optional - Not implemented. + Ignored. Deprecated and will be removed in a release after April 2027. attributes : dict[str, JSON], optional A dictionary of user attributes to store with the array. chunk_shape : ChunksLike, optional diff --git a/tests/test_api.py b/tests/test_api.py index f874bd45b7..534091a03f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2013,8 +2013,26 @@ def test_auto_chunks(f: Callable[..., AnyArray]) -> None: assert a.chunks == (500, 500) -@pytest.mark.parametrize("kwarg_name", ["synchronizer", "chunk_store", "cache_attrs", "meta_array"]) -def test_unimplemented_kwarg_warnings(kwarg_name: str) -> None: +@pytest.mark.parametrize( + "kwarg_name", + [ + "synchronizer", + "chunk_store", + "cache_metadata", + "cache_attrs", + "object_codec", + "read_only", + "meta_array", + ], +) +def test_ignored_kwarg_warnings(kwarg_name: str) -> None: kwargs = {kwarg_name: 1} - with pytest.warns(RuntimeWarning, match=".* is not yet implemented"): + with pytest.warns(ZarrDeprecationWarning, match=f"{kwarg_name} is ignored"): zarr.create(shape=(1,), **kwargs) # type: ignore[arg-type] + + +@pytest.mark.parametrize("kwarg_name", ["synchronizer", "chunk_store", "cache_attrs", "meta_array"]) +def test_ignored_kwarg_warnings_open_group(kwarg_name: str) -> None: + kwargs = {kwarg_name: 1} + with pytest.warns(ZarrDeprecationWarning, match=f"{kwarg_name} is ignored"): + zarr.open_group(store=MemoryStore(), **kwargs) # type: ignore[arg-type] From a11f795b23c424f94bb25ddf476e39d480128f8e Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Sat, 17 Oct 2026 01:46:18 -0400 Subject: [PATCH 2/2] Rename changelog entry --- changes/{3976.removal.md => 4522.removal.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changes/{3976.removal.md => 4522.removal.md} (100%) diff --git a/changes/3976.removal.md b/changes/4522.removal.md similarity index 100% rename from changes/3976.removal.md rename to changes/4522.removal.md