Skip to content

fix: byte-order handling for structured dtypes in the bytes codec#4142

Merged
d-v-b merged 7 commits into
zarr-developers:mainfrom
d-v-b:claude/zarr-python-4141-543977
Jul 14, 2026
Merged

fix: byte-order handling for structured dtypes in the bytes codec#4142
d-v-b merged 7 commits into
zarr-developers:mainfrom
d-v-b:claude/zarr-python-4141-543977

Conversation

@d-v-b

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

Copy link
Copy Markdown
Contributor

Summary

This fix ensures that structured data types are properly recognized as having byte-order sensitivity by the bytes codec at decode time.

Because struct and structured don't implement HasEndianness, chunks with these data types were not handled correctly in the bytes codec decode and encode routines. This change ensures that the byteswapping is correctly applied when the in-memory chunk doesn't match the endianness pledged by the bytes codec during encoding, and also that byteswapping is done when a decoded chunk doesn't match the expected memory order of the output data type.

Note that these byteswaps will incur a copy.

closes #4141

Author attestation

  • I am a human, these are my changes, and I have reviewed and understood every change and can explain why each is correct.

AI coding assistance is welcome, but a human must be the author and is responsible for the contents of the PR. The description and any review responses must be in your own words. Please read AI-assisted contributions before opening.

TODO

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/
  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

d-v-b added 4 commits July 13, 2026 15:47
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
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
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
@d-v-b d-v-b requested a review from ilan-gold July 13, 2026 13:58
@d-v-b

d-v-b commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

this fix reveals a flaw in our HasEndianness type: although the struct data type "has" endianness in the sense that it contains data types with byte order semantics, it doesn't have a literal .endianness attribute. we might need to formalize the concept of "contains other data types" to make it clear that any data type checks have to check the contained data types

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.84%. Comparing base (de2cce1) to head (9d0d0a0).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4142      +/-   ##
==========================================
- Coverage   93.87%   93.84%   -0.04%     
==========================================
  Files          91       91              
  Lines       12564    12570       +6     
==========================================
+ Hits        11795    11796       +1     
- Misses        769      774       +5     
Files with missing lines Coverage Δ
src/zarr/codecs/bytes.py 98.80% <100.00%> (+0.09%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@emfdavid emfdavid left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for fixing this so fast!

@d-v-b d-v-b enabled auto-merge (squash) July 14, 2026 11:25
@d-v-b d-v-b merged commit bbe27d7 into zarr-developers:main Jul 14, 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.

v3 structured dtype serialization drops per-field endianness (silent byte-order loss on metadata roundtrip)

3 participants