Skip to content

fix: remove attribute nesting depth limit - #4330

Draft
d-v-b wants to merge 2 commits into
zarr-developers:mainfrom
d-v-b:codex/remove-attribute-depth-limit
Draft

fix: remove attribute nesting depth limit#4330
d-v-b wants to merge 2 commits into
zarr-developers:mainfrom
d-v-b:codex/remove-attribute-depth-limit

Conversation

@d-v-b

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

Copy link
Copy Markdown
Contributor

🤖 ai text below 🤖

Summary

A Zarr v3 array can be created with attributes nested more than 64 levels deep, but reopening the same array fails with ValueError: JSON value nesting exceeds the maximum depth of 64. This restriction was introduced in #4063 and regresses the behavior in 3.3.0.

Remove the recursive attribute validator and its depth limit, restoring the existing attribute handling through the JSON reader/writer and the metadata constructor. Keep msgspec validation for structured metadata fields. Update the unreleased changelog entry and add create/reopen regression coverage for nested objects and arrays at depths 0, 65, and 100, for both Zarr formats.

For reviewers

Please check that the restored attribute handling is consistent with array creation and group metadata. This draft is awaiting the human author's edits and review before it is marked ready.

Validation on current upstream main plus this fix: 2,188 tests passed and 48 skipped across the JSON parsing, metadata, group, and array suites in the Python 3.12 minimal Hatch environment. Ruff lint and formatting checks and git diff --check passed.

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.

TODO

  • Add regression tests
  • Update the existing unreleased changelog entry
  • Human author edits the description and reviews the changes
  • GitHub Actions have all passed
  • Codecov passes

@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.29%. Comparing base (542ceba) to head (f6a8719).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4330      +/-   ##
==========================================
- Coverage   94.30%   94.29%   -0.01%     
==========================================
  Files          92       92              
  Lines       12915    12893      -22     
==========================================
- Hits        12180    12158      -22     
  Misses        735      735              
Files with missing lines Coverage Δ
src/zarr/core/json_parse.py 100.00% <100.00%> (ø)
src/zarr/core/metadata/v3.py 95.42% <100.00%> (ø)

... and 2 files with indirect coverage changes

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

chunk_key_encoding=_data_typed["chunk_key_encoding"], # type: ignore[arg-type]
codecs=_data_typed["codecs"],
attributes=validate_json_value(_data_typed.get("attributes", {})), # type: ignore[arg-type]
attributes=_data_typed.get("attributes", {}), # type: ignore[arg-type]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

add a comment explaining why we don't validate here

Comment thread tests/test_array.py Outdated
@pytest.mark.parametrize("zarr_format", [2, 3])
@pytest.mark.parametrize("depth", [0, 65, 100])
@pytest.mark.parametrize("container", ["object", "array"])
def test_reopen_nested_attributes(zarr_format: ZarrFormat, depth: int, container: str) -> None:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

surely this test is redundant. we need to simply add a deep attributes example to existing round-trip tests.

Review on the PR: the standalone test_reopen_nested_attributes was
redundant with the round-trip tests that already exist. Drop it and add
a 100-level attributes value in two of them instead: the
ArrayV3Metadata.from_dict/to_dict table in test_v3.py (the layer where
the limit lived) and test_update_attrs in test_array.py, which creates
an array, writes attributes and reopens it for both Zarr formats — the
user-visible path that regressed. Both new cases fail on main with
"nesting exceeds the maximum depth of 64" and pass here.

Also add the comment the review asked for at the attributes= line in
from_dict, saying why attributes are not validated there.

Assisted-by: ClaudeCode:claude-fable-5-1
d-v-b added a commit to d-v-b/zarr-python that referenced this pull request Sep 9, 2026
parse_zarr_format needs Literal at runtime for its parse_field type
argument, so zarr-developers#4063 added a function-local import next to the existing
TYPE_CHECKING one. Import it once at module level like the other modules
that commit touched.

The docstring and depth-limit corrections this branch originally carried
are superseded by zarr-developers#4330, which removes the attribute depth limit and the
validate_json_value helper entirely.

Assisted-by: ClaudeCode:claude-fable-5-1
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