diff --git a/changes/3352.bugfix.md b/changes/3352.bugfix.md new file mode 100644 index 0000000000..5ae761497a --- /dev/null +++ b/changes/3352.bugfix.md @@ -0,0 +1 @@ +Fix `zarr.api.asynchronous.open_like` so it can create a new array by default when the target path does not already exist. diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index c751d6a31c..2721647970 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -1300,6 +1300,8 @@ async def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyAsyncArray: The opened array. """ like_kwargs = _like_args(a) | kwargs + if like_kwargs.get("mode") is None: + like_kwargs["mode"] = "a" return await open_array(path=path, **like_kwargs) # type: ignore[arg-type] diff --git a/tests/test_api.py b/tests/test_api.py index 1b4414ae63..a7de5aede3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -168,6 +168,33 @@ async def test_array_like_creation( assert np.all(Array(new_arr)[:] == expect_fill) +@pytest.mark.parametrize("mode_kwargs", [{}, {"mode": None}]) +async def test_open_like_creates_array_by_default( + zarr_format: ZarrFormat, mode_kwargs: dict[str, None] +) -> None: + ref_arr = zarr.create_array( + store={}, + shape=(11, 12), + dtype="uint8", + chunks=(11, 12), + zarr_format=zarr_format, + fill_value=100, + ) + + new_arr = await zarr.api.asynchronous.open_like( + ref_arr, + path="foo", + store={}, + zarr_format=zarr_format, + **mode_kwargs, + ) + + assert new_arr.shape == ref_arr.shape + assert new_arr.chunks == ref_arr.chunks + assert new_arr.dtype == ref_arr.dtype + assert np.all(Array(new_arr)[:] == ref_arr.fill_value) + + # TODO: parametrize over everything this function takes @pytest.mark.parametrize("store", ["memory"], indirect=True) def test_create_array(store: Store, zarr_format: ZarrFormat) -> None: