Skip to content

fix(array): keep other fields intact when writing one field of a structured array - #4503

Draft
d-v-b wants to merge 4 commits into
zarr-developers:mainfrom
d-v-b:fix/structured-field-writes
Draft

d-v-b wants to merge 4 commits into
zarr-developers:mainfrom
d-v-b:fix/structured-field-writes

Conversation

@d-v-b

@d-v-b d-v-b commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

🤖 AI text below 🤖

Writing one field of a structured array (fields="b") no longer overwrites the other fields of each selected record. Passing a tuple that names several fields to a write now raises IndexError, as a list already did.

On main, _set_selection validates fields and then drops it, casting the value to the full structured dtype. For example, z.set_basic_selection(slice(None), np.full(10, 7.0), fields="b") sets every field of every record to 7. This happens for v2, v3, and sharded v3 arrays, and for basic, orthogonal, coordinate, mask, and block writes.

With this change, a field write reads the selected records into a full-dtype buffer, assigns the field, and writes the whole records back. Missing chunks are read as the fill value even when read_missing_chunks is false, as they are for any partial chunk write. The cost is one extra read of the selection, and only field writes pay it. Like any partial-chunk write, the read and the write are not atomic.

Tests:

  • test_set_selections_with_fields was marked xfail with the reason "fields are not supported in v3". It now runs, filtering only the UnstableSpecificationWarning for its S3 field. Its multi-field cases passed a 3-element value to a 2-element selection, so a shape check fired before the multi-field check; they now pass matching values.
  • New test_set_field_preserves_other_fields covers v2, v3, and sharded v3, with read_missing_chunks true and false, using every selection type, including a partly written chunk and a missing shard. It fails on main and passes here.
  • New test_set_multiple_fields_as_tuple_raises checks the tuple error case.
Context

The agent found this bug while reviewing #3996, which fixes the read side (fields= reads raise TypeError on v2 and v3). This PR fixes writes only and does not depend on #3996. test_get_selections_with_fields stays xfailed until the read fix lands. This PR replaces the agent's fork draft d-v-b#400; both use the same branch.

🤖 Generated with Claude Code

d-v-b added 2 commits October 9, 2026 18:14
…ctured array

`_set_selection` validated `fields` and then dropped it, casting the value to
the full structured dtype. Writing `fields="b"` therefore broadcast the value
into every field of each selected record. Field writes now read the selected
records, replace the named field, and write the whole records back. A tuple
naming several fields is rejected like a list.

Assisted-by: ClaudeCode:claude-opus-5-5
Assisted-by: ClaudeCode:claude-opus-5-5
@d-v-b d-v-b added this to the 3.4.2 milestone Oct 9, 2026
@codecov

codecov Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.33333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.76%. Comparing base (bd0dc84) to head (4423e60).

Files with missing lines Patch % Lines
src/zarr/core/array.py 90.90% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4503      +/-   ##
==========================================
+ Coverage   94.71%   94.76%   +0.05%     
==========================================
  Files          94       94              
  Lines       13663    13668       +5     
==========================================
+ Hits        12941    12953      +12     
+ Misses        722      715       -7     
Files with missing lines Coverage Δ
src/zarr/core/indexing.py 97.37% <100.00%> (+0.79%) ⬆️
src/zarr/core/array.py 98.44% <90.90%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant