Skip to content

Raise specific errors when failing to open a group. #2298

Closed
@TomAugspurger

Description

@TomAugspurger

Zarr version

v3

Numcodecs version

na

Python Version

na

Operating System

na

Installation

na

Description

Zarr 2.x raised a zarr.errors.GroupNotFoundError when failing to open a group.

3.x currently raises a ValueError while trying to fall back to creating a Group on a read-only store.

Steps to reproduce

In [6]: zarr.open_group(zarr.storage.MemoryStore(), mode="r")  # 2.x
---------------------------------------------------------------------------
GroupNotFoundError                        Traceback (most recent call last)
Cell In[6], line 1
----> 1 zarr.open_group(zarr.storage.MemoryStore(), mode="r")

File ~/gh/zarr-developers/zarr-v2/.direnv/python-3.10/lib/python3.10/site-packages/zarr/hierarchy.py:1578, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, meta_array)
   1576         if contains_array(store, path=path):
   1577             raise ContainsArrayError(path)
-> 1578         raise GroupNotFoundError(path)
   1580 elif mode == "w":
   1581     init_group(store, overwrite=True, path=path, chunk_store=chunk_store)

GroupNotFoundError: group not found at path ''

versus 3.x:

In [2]: zarr.open_group(zarr.storage.MemoryStore(), mode="r")
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
File ~/gh/zarr-developers/zarr-python/src/zarr/api/asynchronous.py:609, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, zarr_format, meta_array, attributes)
    608 try:
--> 609     return await AsyncGroup.open(store_path, zarr_format=zarr_format)
    610 except (KeyError, FileNotFoundError):

File ~/gh/zarr-developers/zarr-python/src/zarr/core/group.py:179, in AsyncGroup.open(cls, store, zarr_format)
    178 if zarr_json_bytes is None and zgroup_bytes is None:
--> 179     raise FileNotFoundError(
    180         f"could not find zarr.json or .zgroup objects in {store_path}"
    181     )
    182 # set zarr_format based on which keys were found

FileNotFoundError: could not find zarr.json or .zgroup objects in memory://4519879936

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 zarr.open_group(zarr.storage.MemoryStore(), mode="r")

File ~/gh/zarr-developers/zarr-python/src/zarr/_compat.py:43, in _deprecate_positional_args.<locals>._inner_deprecate_positional_args.<locals>.inner_f(*args, **kwargs)
     41 extra_args = len(args) - len(all_args)
     42 if extra_args <= 0:
---> 43     return f(*args, **kwargs)
     45 # extra_args > 0
     46 args_msg = [
     47     f"{name}={arg}"
     48     for name, arg in zip(kwonly_args[:extra_args], args[-extra_args:], strict=False)
     49 ]

File ~/gh/zarr-developers/zarr-python/src/zarr/api/synchronous.py:212, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, zarr_format, meta_array)
    197 @_deprecate_positional_args
    198 def open_group(
    199     store: StoreLike | None = None,
   (...)
    209     meta_array: Any | None = None,  # not used in async api
    210 ) -> Group:
    211     return Group(
--> 212         sync(
    213             async_api.open_group(
    214                 store=store,
    215                 mode=mode,
    216                 cache_attrs=cache_attrs,
    217                 synchronizer=synchronizer,
    218                 path=path,
    219                 chunk_store=chunk_store,
    220                 storage_options=storage_options,
    221                 zarr_version=zarr_version,
    222                 zarr_format=zarr_format,
    223                 meta_array=meta_array,
    224             )
    225         )
    226     )

File ~/gh/zarr-developers/zarr-python/src/zarr/core/sync.py:91, in sync(coro, loop, timeout)
     88 return_result = next(iter(finished)).result()
     90 if isinstance(return_result, BaseException):
---> 91     raise return_result
     92 else:
     93     return return_result

File ~/gh/zarr-developers/zarr-python/src/zarr/core/sync.py:50, in _runner(coro)
     45 """
     46 Await a coroutine and return the result of running it. If awaiting the coroutine raises an
     47 exception, the exception will be returned.
     48 """
     49 try:
---> 50     return await coro
     51 except Exception as ex:
     52     return ex

File ~/gh/zarr-developers/zarr-python/src/zarr/api/asynchronous.py:611, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, zarr_format, meta_array, attributes)
    609     return await AsyncGroup.open(store_path, zarr_format=zarr_format)
    610 except (KeyError, FileNotFoundError):
--> 611     return await AsyncGroup.from_store(
    612         store_path,
    613         zarr_format=zarr_format or _default_zarr_version(),
    614         exists_ok=True,
    615         attributes=attributes,
    616     )

File ~/gh/zarr-developers/zarr-python/src/zarr/core/group.py:147, in AsyncGroup.from_store(cls, store, attributes, exists_ok, zarr_format)
    142 attributes = attributes or {}
    143 group = cls(
    144     metadata=GroupMetadata(attributes=attributes, zarr_format=zarr_format),
    145     store_path=store_path,
    146 )
--> 147 await group._save_metadata(ensure_parents=True)
    148 return group

File ~/gh/zarr-developers/zarr-python/src/zarr/core/group.py:300, in AsyncGroup._save_metadata(self, ensure_parents)
    290     for parent in parents:
    291         awaitables.extend(
    292             [
    293                 (parent.store_path / key).set_if_not_exists(value)
   (...)
    297             ]
    298         )
--> 300 await asyncio.gather(*awaitables)

File ~/gh/zarr-developers/zarr-python/src/zarr/abc/store.py:348, in set_or_delete(byte_setter, value)
    346     await byte_setter.delete()
    347 else:
--> 348     await byte_setter.set(value)

File ~/gh/zarr-developers/zarr-python/src/zarr/storage/common.py:49, in StorePath.set(self, value, byte_range)
     47 if byte_range is not None:
     48     raise NotImplementedError("Store.set does not have partial writes yet")
---> 49 await self.store.set(self.path, value)

File ~/gh/zarr-developers/zarr-python/src/zarr/storage/memory.py:91, in MemoryStore.set(self, key, value, byte_range)
     90 async def set(self, key: str, value: Buffer, byte_range: tuple[int, int] | None = None) -> None:
---> 91     self._check_writable()
     92     await self._ensure_open()
     93     assert isinstance(key, str)

File ~/gh/zarr-developers/zarr-python/src/zarr/abc/store.py:123, in Store._check_writable(self)
    121 def _check_writable(self) -> None:
    122     if self.mode.readonly:
--> 123         raise ValueError("store mode does not support writing")

ValueError: store mode does not support writing

Additional output

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugPotential issues with the zarr-python library

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions