Skip to content

fix: allow writing to 0-dimensional arrays with sharding - #3966

Merged
d-v-b merged 3 commits into
zarr-developers:mainfrom
NIK-TIGER-BILL:fix-3751-zero-dim-sharding
May 14, 2026
Merged

fix: allow writing to 0-dimensional arrays with sharding#3966
d-v-b merged 3 commits into
zarr-developers:mainfrom
NIK-TIGER-BILL:fix-3751-zero-dim-sharding

Conversation

@NIK-TIGER-BILL

Copy link
Copy Markdown
Contributor

Closes#3751

This PR fixes a bug where writing to a 0-dimensional array with sharding enabled would crash with an IndexError in the sharding codec's vectorized chunk slice lookup.

The root cause was that get_chunk_slices_vectorized in zarr/codecs/sharding.py assumed offsets_and_lengths was at least 2-dimensional, but for 0-dimensional arrays it has shape (2,) instead of (1, 2). This caused offsets_and_lengths[:, 0] to fail with "too many indices for array".

Fix: Add an early return in get_chunk_slices_vectorized to handle the 0-dimensional case by reshaping offsets_and_lengths to (1, 2) before slicing.

Test: Added test_sharding_zero_dimensional in tests/test_codecs/test_sharding.py as a regression test.

@github-actionsgithub-actionsBot added the needs release notes Automatically applied to PRs which haven't added release notes label May 11, 2026
@codecov

codecovBot commented May 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.29%. Comparing base (eac9c86) to head (bb315a8).

Additional details and impacted files
@@ Coverage Diff @@## main #3966 +/- ##
==========================================
+ Coverage 93.28% 93.29% +0.01% 
==========================================
Files 87 87 Lines 11745 11752 +7 ==========================================
+ Hits 10956 10964 +8 + Misses 789 788 -1 
Files with missing linesCoverage Δ
src/zarr/codecs/sharding.py89.32% <100.00%> (+0.23%)⬆️

... 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.

@chuckwondochuckwondo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @NIK-TIGER-BILL!

Would you mind also adding a test that covers your patch that handles the 0D case? The test you added shows that the original case no longer errors, but that case no longer enters the function that you patched, so your patch itself remains untested, hence the failed codecov run.

@NIK-TIGER-BILL

Copy link
Copy Markdown
ContributorAuthor

@chuckwondo Good catch — the integration test bypassed the patched function. I just pushed a direct unit test that exercises _ShardIndex.get_chunk_slices_vectorized with a 0-D offsets_and_lengths array, covering both the written and unwritten chunk cases. This should satisfy codecov for the new branch. Let me know if you would like anything else adjusted!

@chuckwondo

Copy link
Copy Markdown
Contributor

Thanks @NIK-TIGER-BILL. Would you mind updating your branch and addressing the ruff pre-commit error? (See https://results.pre-commit.ci/run/github/48049137/1778641889.s58oPP4KQbGdn7pJdtUPAg)

@maxrjones and/or @d-v-b, please review.

NIK-TIGER-BILL added 3 commits May 13, 2026 23:00
Signed-off-by: NIK-TIGER-BILL <nik.tiger.bill@github.com>
Signed-off-by: NIK-TIGER-BILL <nik.tiger.bill@github.com>
Signed-off-by: NIK-TIGER-BILL <nik.tiger.bill@github.com>
@NIK-TIGER-BILL
NIK-TIGER-BILLforce-pushed the fix-3751-zero-dim-sharding branch from 411cf37 to bb315a8CompareMay 13, 2026 23:01
@NIK-TIGER-BILL

Copy link
Copy Markdown
ContributorAuthor

@chuckwondo Done — rebased on latest upstream/main and fixed the ruff unused-variable error (prefixed ends_e with an underscore). CI should be green now. Let me know if anything else is needed!

@NIK-TIGER-BILL

Copy link
Copy Markdown
ContributorAuthor

@chuckwondo I believe I've addressed all feedback — rebased on latest upstream/main and fixed the ruff unused-variable issue (prefixed with ). Could you please take another look when you have a moment? Thanks!

@chuckwondo

Copy link
Copy Markdown
Contributor

@d-v-b, this is a very small PR. Looks good to me, but would you mind reviewing as well?

@chuckwondochuckwondo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@d-v-b

Copy link
Copy Markdown
Contributor

this looks good! there's some baseline code smell in these classes but this fix is appropriately targeted. I'll open an issue with my follow-up recommendations.

@d-v-b
d-v-b merged commit fcb3cd3 into zarr-developers:mainMay 14, 2026
30 checks passed
d-v-b added a commit to d-v-b/zarr-python that referenced this pull request May 15, 2026
Resolve conflicts in tests/test_codecs/test_sharding.py: combine the
imports from both sides (INDEX_LOCATION/IndexLocation/ShardingCodecIndexLocation
from our deprecation work, plus MAX_UINT_64/_ShardIndex from zarr-developers#3966's 0-D
sharding fix), and keep all added test functions from both branches.
Other auto-merged files (src/zarr/codecs/sharding.py and
src/zarr/core/buffer/core.py) merged cleanly: upstream's 0-D path and
NDArrayLike protocol tightening sit alongside our enum deprecation
changes without overlap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@d-v-bd-v-b mentioned this pull request Jul 15, 2026
d-v-b added a commit that referenced this pull request Jul 16, 2026
* chore(deps): bump the actions group across 1 directory with 8 updates (#176)
Bumps the actions group with 8 updates in the / directory:
| Package | From | To |
| --- | --- | --- |
| [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` |
| [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `6.0.1` |
| [github/issue-metrics](https://github.com/github/issue-metrics) | `4.2.2` | `4.2.7` |
| [j178/prek-action](https://github.com/j178/prek-action) | `2.0.3` | `2.0.4` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `7.0.0` | `8.0.1` |
| [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.3` | `0.5.6` |
Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6
- [Release notes](https://github.com/prefix-dev/setup-pixi/releases)
- [Commits](prefix-dev/setup-pixi@1b2de7f...5185adf)
Updates `codecov/codecov-action` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@57e3a13...e79a696)
Updates `github/issue-metrics` from 4.2.2 to 4.2.7
- [Release notes](https://github.com/github/issue-metrics/releases)
- [Commits](github-community-projects/issue-metrics@c9e9838...1e38d5e)
Updates `j178/prek-action` from 2.0.3 to 2.0.4
- [Release notes](https://github.com/j178/prek-action/releases)
- [Commits](j178/prek-action@6ad8027...bdca6f1)
Updates `actions/upload-artifact` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v7...043fb46)
Updates `actions/download-artifact` from 7.0.0 to 8.0.1
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@v7...3e5f45b)
Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](pypa/gh-action-pypi-publish@v1.13.0...cef2210)
Updates `zizmorcore/zizmor-action` from 0.5.3 to 0.5.6
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](zizmorcore/zizmor-action@b1d7e1f...5f14fd0)
---
updated-dependencies:
- dependency-name: prefix-dev/setup-pixi
dependency-version: 0.9.6
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
- dependency-name: codecov/codecov-action
dependency-version: 6.0.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
- dependency-name: github/issue-metrics
dependency-version: 4.2.7
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
- dependency-name: j178/prek-action
dependency-version: 2.0.4
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
- dependency-name: actions/upload-artifact
dependency-version: 7.0.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
- dependency-name: actions/download-artifact
dependency-version: 8.0.1
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: actions
- dependency-name: pypa/gh-action-pypi-publish
dependency-version: 1.14.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: actions
- dependency-name: zizmorcore/zizmor-action
dependency-version: 0.5.6
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: actions
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix: byte-order handling for structured dtypes in the bytes codec (#220)
* 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#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
* docs: 3.3.0 release notes
Add missing changelog fragments for #3955 (datetime64/timedelta64 V3
metadata types), #3966 (writes to 0-dimensional sharded arrays), and the
public alias renames that accompanied the #3963/#3968 enum deprecations,
then build the 3.3.0 release notes with towncrier, consuming all
fragments accumulated since v3.2.1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs release notesAutomatically applied to PRs which haven't added release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot write a 0 dimensional array with sharding

3 participants

@NIK-TIGER-BILL@chuckwondo@d-v-b