Skip to content

Fix/memorystore buffer aliasing#4157

Merged
d-v-b merged 7 commits into
zarr-developers:mainfrom
d-v-b:fix/memorystore-buffer-aliasing
Jul 17, 2026
Merged

Fix/memorystore buffer aliasing#4157
d-v-b merged 7 commits into
zarr-developers:mainfrom
d-v-b:fix/memorystore-buffer-aliasing

Conversation

@d-v-b

@d-v-b d-v-b commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@maxrjones ran a regression check on our pre-3.3.0 release state, and found a few regressions that need fixing. Here's the first fix, which ensures that memory storage always copies buffers, instead of hanging on to aliases of arrays owned by the caller.

this PR was written by claude code and opened by me; to view claude's original output, see d-v-b#224

d-v-b added 4 commits July 14, 2026 13:25
* fix: byte-order handling for structured dtypes in the bytes codec

The bytes codec neither byte-swapped structured-dtype fields to its
configured endian on encode (numpy reports byteorder '|' for void
dtypes, so the top-level byteorder comparison never detected a
mismatch) nor honored its endian when decoding, silently corrupting
any structured data whose field byte order differed from the stored
one (e.g. virtual references to external big-endian data).

Encode now detects byte-order mismatches by comparing full dtypes via
newbyteorder, and decode reinterprets raw bytes in the stored byte
order before converting to the data type's declared byte order, so the
stored layout (codec state) and the in-memory layout (array data type)
are independent.

Closes zarr-developers#4141

Assisted-by: ClaudeCode:claude-fable-5

* test: fold structured byte-order cases into existing bytes codec tests

Extend test_endian's parametrization with structured dtypes and
test_bytes_codec_sync_roundtrip with endian/dtype parametrization plus
stored-layout and decoded-dtype assertions, instead of adding parallel
test functions for the same properties.

Assisted-by: ClaudeCode:claude-fable-5

* refactor: rename stored_dtype to view_dtype in BytesCodec decode

The variable is the dtype used to view the raw chunk bytes (byte order
from the codec's endian configuration), not a property of the stored
data or of the returned buffer, which always carries the array's
declared dtype.

Assisted-by: ClaudeCode:claude-fable-5

* docs: note that the decode-side byte-order conversion copies the chunk

Assisted-by: ClaudeCode:claude-fable-5
Encoding an uncompressed chunk hands the store a zero-copy view of the
caller's array, and MemoryStore keeps whatever it is given alive in a
dict rather than serializing it. Mutating the source array after a write
therefore rewrote chunks already committed to the store, silently.

Stores that serialize on write (LocalStore, ZipStore, remote stores) are
unaffected, so they keep the full benefit of zarr-developers#3885. Only MemoryStore pays
the copy, and only where it was aliasing to begin with: an uncompressed
34 MB write goes from ~23 ms to ~39 ms, while compressed writes are
unchanged.

Copying at the store boundary rather than narrowing the fast path in
_merge_chunk_array also fixes the single-chunk case, which aliased in
v3.2.1 too.

Assisted-by: ClaudeCode:claude-opus-4.8
Assisted-by: ClaudeCode:claude-opus-4.8
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.84%. Comparing base (3265452) to head (5c1bac0).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4157   +/-   ##
=======================================
  Coverage   93.84%   93.84%           
=======================================
  Files          91       91           
  Lines       12570    12572    +2     
=======================================
+ Hits        11796    11798    +2     
  Misses        774      774           
Files with missing lines Coverage Δ
src/zarr/core/buffer/core.py 79.31% <ø> (ø)
src/zarr/storage/_memory.py 96.55% <100.00%> (+0.02%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@d-v-b
d-v-b marked this pull request as ready for review July 17, 2026 11:46
@d-v-b
d-v-b requested a review from maxrjones July 17, 2026 11:56

@maxrjones maxrjones left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks right to me, thanks @d-v-b!

FWIW I also really like the way you've structured your PR with the link to the raw work here.

@d-v-b
d-v-b merged commit 50b7e01 into zarr-developers:main Jul 17, 2026
30 checks passed
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.

2 participants