Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changes/3127.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When `zarr.save` has an argument `path=some/path/` and multiple arrays in `args`, the path resulted in `some/path/some/path` due to using the `path`
argument twice while building the array path. This is now fixed.
3 changes: 1 addition & 2 deletions src/zarr/api/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,12 @@ async def save_group(
raise ValueError("at least one array must be provided")
aws = []
for i, arr in enumerate(args):
_path = f"{path}/arr_{i}" if path is not None else f"arr_{i}"
aws.append(
save_array(
store_path,
arr,
zarr_format=zarr_format,
path=_path,
path=f"arr_{i}",
storage_options=storage_options,
)
)
Expand Down
17 changes: 9 additions & 8 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,22 +229,23 @@ async def test_open_group_unspecified_version(
@pytest.mark.parametrize("store", ["local", "memory", "zip"], indirect=["store"])
@pytest.mark.parametrize("n_args", [10, 1, 0])
@pytest.mark.parametrize("n_kwargs", [10, 1, 0])
def test_save(store: Store, n_args: int, n_kwargs: int) -> None:
@pytest.mark.parametrize("path", [None, "some_path"])
def test_save(store: Store, n_args: int, n_kwargs: int, path: None | str) -> None:
data = np.arange(10)
args = [np.arange(10) for _ in range(n_args)]
kwargs = {f"arg_{i}": data for i in range(n_kwargs)}

if n_kwargs == 0 and n_args == 0:
with pytest.raises(ValueError):
save(store)
save(store, path=path)
elif n_args == 1 and n_kwargs == 0:
save(store, *args)
array = zarr.api.synchronous.open(store)
save(store, *args, path=path)
array = zarr.api.synchronous.open(store, path=path)
assert isinstance(array, Array)
assert_array_equal(array[:], data)
else:
save(store, *args, **kwargs) # type: ignore [arg-type]
group = zarr.api.synchronous.open(store)
save(store, *args, path=path, **kwargs) # type: ignore [arg-type]
group = zarr.api.synchronous.open(store, path=path)
assert isinstance(group, Group)
for array in group.array_values():
assert_array_equal(array[:], data)
Expand Down Expand Up @@ -384,8 +385,8 @@ def test_array_order_warns(order: MemoryOrder | None, zarr_format: ZarrFormat) -
# assert "LazyLoader: " in repr(loader)


def test_load_array(memory_store: Store) -> None:
store = memory_store
def test_load_array(sync_store: Store) -> None:
store = sync_store
foo = np.arange(100)
bar = np.arange(100, 0, -1)
save(store, foo=foo, bar=bar)
Expand Down