diff --git a/changes/3066.feature.rst b/changes/3066.feature.rst new file mode 100644 index 0000000000..89d5ddb1c6 --- /dev/null +++ b/changes/3066.feature.rst @@ -0,0 +1 @@ +Added `~zarr.errors.GroupNotFoundError`, which is raised when attempting to open a group that does not exist. diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index 5b9c0bee3d..aae7d28d15 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -39,7 +39,7 @@ ) from zarr.core.metadata import ArrayMetadataDict, ArrayV2Metadata, ArrayV3Metadata from zarr.core.metadata.v2 import _default_compressor, _default_filters -from zarr.errors import NodeTypeValidationError +from zarr.errors import GroupNotFoundError, NodeTypeValidationError from zarr.storage._common import make_store_path if TYPE_CHECKING: @@ -836,7 +836,7 @@ async def open_group( overwrite=overwrite, attributes=attributes, ) - raise FileNotFoundError(f"Unable to find group: {store_path}") + raise GroupNotFoundError(store, store_path.path) async def create( diff --git a/src/zarr/errors.py b/src/zarr/errors.py index 441cdab9a3..4d3140a4a9 100644 --- a/src/zarr/errors.py +++ b/src/zarr/errors.py @@ -21,6 +21,14 @@ def __init__(self, *args: Any) -> None: super().__init__(self._msg.format(*args)) +class GroupNotFoundError(BaseZarrError, FileNotFoundError): + """ + Raised when a group isn't found at a certain path. + """ + + _msg = "No group found in store {!r} at path {!r}" + + class ContainsGroupError(BaseZarrError): """Raised when a group already exists at a certain path.""" diff --git a/tests/test_metadata/test_v3.py b/tests/test_metadata/test_v3.py index a47cbf43bb..13549b10a4 100644 --- a/tests/test_metadata/test_v3.py +++ b/tests/test_metadata/test_v3.py @@ -20,7 +20,7 @@ parse_fill_value, parse_zarr_format, ) -from zarr.errors import MetadataValidationError +from zarr.errors import MetadataValidationError, NodeTypeValidationError if TYPE_CHECKING: from collections.abc import Sequence @@ -62,7 +62,8 @@ @pytest.mark.parametrize("data", [None, 1, 2, 4, 5, "3"]) def test_parse_zarr_format_invalid(data: Any) -> None: with pytest.raises( - ValueError, match=f"Invalid value for 'zarr_format'. Expected '3'. Got '{data}'." + MetadataValidationError, + match=f"Invalid value for 'zarr_format'. Expected '3'. Got '{data}'.", ): parse_zarr_format(data) @@ -88,7 +89,8 @@ def test_parse_node_type_invalid(node_type: Any) -> None: @pytest.mark.parametrize("data", [None, "group"]) def test_parse_node_type_array_invalid(data: Any) -> None: with pytest.raises( - ValueError, match=f"Invalid value for 'node_type'. Expected 'array'. Got '{data}'." + NodeTypeValidationError, + match=f"Invalid value for 'node_type'. Expected 'array'. Got '{data}'.", ): parse_node_type_array(data)