Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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