Skip to content
Closed
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
26 changes: 2 additions & 24 deletions src/zarr/api/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,13 +673,6 @@ async def group(

zarr_format = _handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)

mode: AccessModeLiteral
if overwrite:
mode = "w"
else:
mode = "r+"
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)

if chunk_store is not None:
warnings.warn("chunk_store is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
if cache_attrs is not None:
Expand All @@ -689,20 +682,7 @@ async def group(
if meta_array is not None:
warnings.warn("meta_array is not yet implemented", ZarrRuntimeWarning, stacklevel=2)

if attributes is None:
attributes = {}

try:
return await AsyncGroup.open(store=store_path, zarr_format=zarr_format)
except (KeyError, FileNotFoundError):
_zarr_format = zarr_format or _default_zarr_format()
return await AsyncGroup.from_store(
store=store_path,
zarr_format=_zarr_format,
overwrite=overwrite,
attributes=attributes,
)

return await create_group(store=store, path=path, overwrite=overwrite, zarr_format=zarr_format, attributes=attributes, storage_options=storage_options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry I realise my comments are scattergun) If group() is actually meant to try opening a group first (it's not documented like that, but I guess it's existing behaviour we shouldn't break...?), maybe the try/except statement needs putting back, but the new create_group call should go in the except block?


async def create_group(
*,
Expand Down Expand Up @@ -742,9 +722,7 @@ async def create_group(
if zarr_format is None:
zarr_format = _default_zarr_format()

mode: Literal["a"] = "a"

store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
store_path = await make_store_path(store, path=path, mode="a", storage_options=storage_options)

return await AsyncGroup.from_store(
store=store_path,
Expand Down
28 changes: 27 additions & 1 deletion tests/test_api/test_asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import pytest

from zarr import create_array
from zarr.api.asynchronous import _get_shape_chunks, _like_args, open
from zarr.api.asynchronous import _get_shape_chunks, _like_args, group, open
from zarr.core.buffer.core import default_buffer_prototype
from zarr.errors import ContainsGroupError

if TYPE_CHECKING:
from pathlib import Path
from typing import Any

import numpy.typing as npt
Expand Down Expand Up @@ -103,3 +105,27 @@ async def test_open_no_array() -> None:
TypeError, match=r"open_group\(\) got an unexpected keyword argument 'shape'"
):
await open(store=store, shape=(1,))


async def test_open_group_new_path(tmp_path: Path) -> None:
"""
Test that zarr.api.asynchronous.group properly handles a string representation of a local file
path that does not yet exist.

See https://github.com/zarr-developers/zarr-python/issues/3406
"""
# tmp_path exists, but tmp_path / "test.zarr" will not, which is important for this test
store = tmp_path / "test.zarr"
await group(store=store)


async def test_open_group_old_path(tmp_path: Path) -> None:
"""
Test that zarr.api.asynchronous.group will not overwrite an existing file.

See https://github.com/zarr-developers/zarr-python/issues/3406
"""
store = tmp_path
await group(store=store, overwrite=True, attributes={"existing_group": True})
with pytest.raises(ContainsGroupError):
await group(store=store)
2 changes: 1 addition & 1 deletion tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -2159,7 +2159,7 @@ def test_group_members_performance(store: Store) -> None:

latency_store = LatencyStore(store, get_latency=get_latency)
# create a group with some latency on get operations
group_read = zarr.group(store=latency_store)
group_read = zarr.open_group(store=latency_store)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change also caught this, which was trying to create a group on top of another group - I changed it to open the existing roup instead.


# check how long it takes to iterate over the groups
# if .members is sensitive to IO latency,
Expand Down
Loading