fix(group): create group helper arrays in the group's zarr format - #4412
Merged
Merged
Conversation
Group.empty/zeros/ones/full and their *_like versions forwarded **kwargs to the top-level creation functions without the group's zarr_format, so a zarr v2 group got zarr v3 arrays. The group lists only members of its own format, so each array was written into the group without becoming a member of it. Pass the group's format, and raise when the caller asks for another. Creating an array in one format like an array of the other then failed, because _like_args copied format-specific codec settings (compressor and filters, or codecs). _like_args now takes the target format and copies those settings only when the formats match. Top-level *_like functions inherit the source's format unless another is requested; open_like does not, because open_array would then look for an existing array in only that format. Assisted-by: ClaudeCode:claude-opus-5-5
Assisted-by: ClaudeCode:claude-opus-5-5
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4412 +/- ##
==========================================
+ Coverage 94.46% 94.48% +0.01%
==========================================
Files 93 93
Lines 13233 13245 +12
==========================================
+ Hits 12501 12514 +13
+ Misses 732 731 -1
🚀 New features to boost your workflow:
|
`empty_like`, `zeros_like`, `ones_like`, `full_like` and `open_like` read the
target format with `kwargs.get("zarr_format")` and then merged `kwargs` over
the arguments derived from the source array. An explicit `zarr_format=None`
therefore made `_like_args` inherit the source's format and copy its codecs,
after which the merge put `None` back and `create` chose the default format:
`zarr.zeros_like(v2_array, zarr_format=None)` raised because v2 compressor
settings reached a v3 array. `zarr_format` is now a keyword-only parameter,
and `_like_args` records the resolved format in the arguments it returns.
Assisted-by: ClaudeCode:claude-opus-5-5
d-v-b
marked this pull request as ready for review
September 30, 2026 16:07
This was referenced Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 fixes a silly bug where v2 groups would support the creation of v3 arrays. there's a deeper problem here (our group class isn't v2 or v3 flavored) but this PR fixes the superficial problem (the incorrect behavior).
🤖 AI text below 🤖
Group.empty,zeros,ones,fulland their*_likeversions now create arrays in the zarr format of the group. Previously a zarr v2 group got zarr v3 arrays, which were written into the group without becoming members of it. Creating an array like an array of the other zarr format (for examplezarr.zeros_like(v2_array)) no longer fails. The new array uses the default codecs of its own format, and top-level*_likefunctions inherit the zarr format of the source array unlesszarr_formatis passed.Cause
Group.empty/zeros/ones/fulland their*_likeversions forwarded**kwargsto the top-level creation functions without the group'szarr_format. A zarr v2 group therefore got zarr v3 arrays. The group lists only members of its own format, so each array was written into the group's path without becoming a member of it:The agent found this during the same
**kwargsaudit that produced #4408 and #4410.Group.create_arrayalready passeszarr_format=self.metadata.zarr_format; these helpers did not.Changes
AsyncGroup._member_zarr_formatsupplies the group's format to all eight helpers. The syncGroupmethods delegate to these. An explicitzarr_formatthat differs from the group's raisesValueError._like_argscopied format-specific codec settings (compressor/filters/orderfor v2,codecsfor v3). For example,zarr.zeros_like(v2_array)raisedValueError: compressor cannot be used for arrays with zarr_format 3onmain._like_argsnow takes the target format and copies codec settings only when the formats match.test_group_array_like_creation[zarr2-...]cases passed onmainonly because the v2 group was silently getting v3 arrays.empty_like/zeros_like/ones_like/full_likenow inherit the zarr format of a zarr source array unlesszarr_formatis passed. That matches what "like" suggests, and zarr 2.x behaviour.zarr_formatis now a named, keyword-only parameter of the top-levelempty_like/zeros_like/ones_like/full_like/open_like, sync and async, where these functions used to read it out of**kwargs. Withkwargs.get("zarr_format"), an explicitzarr_format=Nonemade_like_argsinherit the source's format and copy its codecs, and then| kwargsmerged theNoneback over that inherited format.createthen chose the default format, sozarr.zeros_like(v2_array, zarr_format=None)raised._like_argsnow puts the format it settles on into the arguments it returns, andopen_liketakes it back out so thatopen_arraystill looks for an existing array in either format.open_likedoes not inherit the source's format. If it did,open_arraywould look for an existing array in only that format. A v2 source pointed at an existing v3 array would then write a second (v2) array at the same path, because the v2 existence check doesn't seezarr.json.open_liketargets the requested or default format, as before. A missing target is now created with that format's default codecs instead of raising.Tests
test_group_array_helpers_use_group_format: group format 2/3 × eight helpers × source format 2/3 × with or without an explicit matchingzarr_format. Checks that the array has the group's format and is listed by the group.test_group_array_helpers_other_format: the one error case, a mismatchedzarr_format.test_like_zarr_format: top-level*_like× source format × requested format (including an explicitzarr_format=None). Checks the resulting format, and that codecs are kept only when the formats match.test_open_like_zarr_format: an existing target of either format is opened as-is, and a missing one is created in the default format.test_like_argsgains azarr_formatargument and cases for inheriting and for crossing formats. The returned arguments include the zarr format the function settled on.On
main, 41 of the new group and*_likecases and oneopen_likecase fail. The full test suite passes locally, and so does mypy.Not covered
ensure_no_existing_node(zarr_format=2)doesn't detect an existing v3 node, and vice versa, so an array of one format can still be created over a node of the other through other paths (seetest_v2_and_v3_exist_at_same_path). This PR avoids reaching that throughopen_likebut doesn't change the check itself.🤖 Generated with Claude Code