restore v2-like exceptions #3012
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR brings the following changes:
new (old) exceptions
zarr.errors
gets new exceptionsArrayNotFoundError
,GroupNotFoundError
,PathNotFoundError
,NodeNotFoundError
(for when neither an array nor a group were found, in a context where either one was a valid result). The first three existed in zarr-python 2, so this PR is restoring compatibility. The newNodeNotFoundError
is an instance of the zarr-python 2 exceptionPathNotFoundError
. This subclass relationship exists for zarr-python 2 compatibility -- users coming from zarr-python 2 can usetry..., except PathNotFoundError
and catch theNodeNotFoundError
.PathNotFoundError
is deprecated but does not emit a warning on use. We should decide when to remove it.PathNotFoundError
is deprecated because the name of that exception is inconsistent withArrayNotFoundError
andGroupNotFoundError
, which take the form<thing at a path>NotFoundError
.PathNotFoundError
is raised when a path fails to resolve to a node, i.e. an array or group, even if something is at that path. Because the name is bad (IMO), we should remove this exception entirely in the future. Until then,NodeNotFoundError
inherits fromPathNotFoundError
, and we should useNodeNotFoundError
in the codebase.We were using
FileNotFoundError
andKeyError
to model "failure to find an array or group at a path." In this PR, we consistently useArrayNotFoundError
when failing to find an array,GroupNotFoundError
when failing to find a group, andNodeNotFoundError
when failing to find either an array or group, in a context where either would have been OK (e.g.,zarr.open()
orgroup['nodea_name']
).relaxed exception formatting
In this PR, exceptions defined in
zarr.errors
take a single string in their constructor. This is a change frommain
, where the exceptions take a tuple of values that will be inserted into an f-string defined in the exception class.That is, in
main
,raise FooError('a', 'b')
will emitFooError: predefined message with two args, 'a' and 'b'
, but in this PR, you would need to invokeraise FooError("predefined message with two args, 'a', 'b'")
to get the same message.The acute reason for this change is to allow the same exception to contain a contextualized message. In the case of missing arrays or groups, it's useful to tell the user in e.g. an
ArrayNotFoundError
which zarr format the code was looking for, which means failing to find a v2 array or a v3 array (or either, if zarr_format was unspecified) each requires a slightly different message.A more general reason for this change is that (IMO) pre-defining an exception message in the exception class is not good design. The exception text is read by humans, so it should convey whatever is most helpful in the context of that exception, and this might vary in different contexts. The exception message does not need to be highly structured for this purpose (it will not be read by machines), and if we do for some reason want our exceptions to be highly structured, then we can write separate functions that generate a pre-formatted exception message, and use this function before calling the exception. A cost of this approach is that it's a little more work to write exception messages, but the gain in expressiveness is worth it IMO.
partially addresses #3009 and #2821