You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 4b9f82c
Browse filesBrowse the repository at this point in the historyBrowse files
fix(group): store a group's documents only; keep upgraded members as stored
Group writes (attributes, `update_attributes`, deleting a member,
`consolidate_metadata`, `create_hierarchy`) read each upgraded member of
the consolidated metadata again from its own document and stored its
upgrade. Those member writes raced concurrent deletions: two concurrent
`delitem`s on a consolidated group recreated a deleted array's metadata
document in most runs, which zarr 3.4.0 never did.
A group write now stores only the group's own documents and reads none.
Array metadata read from a document that had to be upgraded keeps that
document (`_stored_document`, set by `mark_upgraded`, replacing the
`_stored_document_upgraded` flag), and consolidated metadata stores such
a member as it was stored. Every reader of the consolidated metadata then
reads the member as upgraded again, and the array's own first chunk write
stores the upgrade of its current document (or refuses a changed chunk
grid) as before: the only write that upgrades a member document.
Removed: the refresh and adoption of consolidated members in
`save_metadata` (`_refresh_consolidated`, `_refresh_array`,
`_Refreshed`), and `Group.update_attributes_async`'s detour through
`save_metadata`. Tests pinning the refresh are replaced by tests that a
group write reads nothing and writes only the group's documents, stores
the member's consolidated copy byte for byte as stored, that concurrent
deletions leave no member, and that the first write through consolidated
metadata stores the member's upgrade or refuses a changed grid.
Assisted-by: ClaudeCode:claude-opus-5-5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: changes/4334.bugfix.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,4 +4,4 @@ A chunk edge length is now always at least 1, while an array extent may be 0. Ev
4
4
5
5
Stored metadata with a regular chunk size of 0 or JSON `false` (Zarr format 2 `chunks`, Zarr format 3 `regular` `chunk_shape`) is now read as one chunk spanning the axis (a multiple of the inner chunk size for sharded arrays, which previously failed to open). zarr-python wrote such sizes for arrays created with a zero-length axis until 3.4, and, from 2.18.7 to 3.2.1, for an explicit chunk size of 0 or `False` on an axis of any length, as in `chunks=(0,)` (those arrays could store no data). On a zero-length axis this opens silently, as before; appending to such an axis then stores chunks of size 1. On an axis of positive length it opens with a `ZarrUserWarning`, which says that the axis holds only the fill value and how to store valid metadata: `array.update_attributes({})`, then `zarr.consolidate_metadata` if the metadata is consolidated. JSON `true`, as zarr-python 3.0 and 3.2 wrote for a chunk size of `True`, is read as 1, silently, in the chunk grid (regular, and the explicit edges and run-length encoded sizes of a rectilinear one) and in the inner chunk shape of every sharding codec, nested or not. A stored rectilinear chunk grid whose edge lengths are integral JSON floats (`[[4.0, 2]]`), as zarr-python 3.2 wrote for float edges, is read with those edges as integers, silently; a float anywhere no release wrote one (a regular chunk shape, the inner chunk shape of a sharding codec, a run-length repeat count, an edge below 1) is rejected.
6
6
7
-
Writing data to an array read from such metadata (other than an empty selection) first stores the upgrade of the metadata the store then holds, unless another writer has stored valid metadata since, so that other readers find the chunks written; in a `ZipStore` this adds a second entry for the metadata document, as every metadata update does. If the metadata the store then holds lays out chunks differently (another writer resized the array keeping the chunk size of 0, say), the write raises a `ValueError` asking to reopen the array, and stores nothing. Storing a group's metadata, which `zarr.consolidate_metadata` and every change to a group with consolidated metadata do, likewise first stores the upgrade of each such member's metadata and consolidates the member's metadata as the store then holds it.
7
+
Writing data to an array read from such metadata (other than an empty selection) first stores the upgrade of the metadata the store then holds, unless another writer has stored valid metadata since, so that other readers find the chunks written; in a `ZipStore` this adds a second entry for the metadata document, as every metadata update does. If the metadata the store then holds lays out chunks differently (another writer resized the array keeping the chunk size of 0, say), the write raises a `ValueError` asking to reopen the array, and stores nothing. This is the only operation that stores the upgrade: a group's consolidated metadata keeps such an array's metadata as it was stored (`zarr.consolidate_metadata` copies it as the array's own document holds it), and changing a group reads and writes no metadata of its members.
0 commit comments