diff --git a/changes/4522.removal.md b/changes/4522.removal.md new file mode 100644 index 0000000000..b4e5a439f0 --- /dev/null +++ b/changes/4522.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]