Commit cd7d264
committed
fix(chunk-grids): enforce one zero-length-axis invariant across model, clamps and metadata
Invariant: a chunk edge length is always >= 1; a dimension's extent may be 0,
in which case the dimension has zero chunks (ceildiv(0, size) == 0).
Zero-length-axis bugs have recurred since 2017 (#150, #241, #303, zarr-developers#972,
zarr-developers#1977, zarr-developers#2434, zarr-developers#3711, zarr-developers#4305, zarr-developers#4307, zarr-developers#4328) because the layers disagreed on
this invariant and every span-derived chunk spelling clamped on its own:
- The metadata layer (common.py, metadata/v3.py) required chunk edges >= 1,
but the in-memory FixedDimension allowed size == 0 with four special-case
branches left over from zarr-developers#2434, so normalization could build a grid the
metadata constructor then rejected. FixedDimension now rejects size < 1
and the four `if self.size == 0` branches are gone. VaryingDimension
already required edges > 0 and is unchanged.
- `chunks=-1`, `chunks=False`, `chunks="auto"` (_guess_regular_chunks, both
the typesize == 0 early return and the np.maximum line) and `shards="auto"`
each derived "one chunk covering the axis" independently. They now all go
through one helper, `_full_span_chunk_size(span) = max(span, 1)`, which is
the single definition of that phrase for a possibly zero-length axis.
- Zarr format 2 metadata had no chunk >= 1 check, so a legacy `chunks: [0]`
document opened fine and read uninitialised memory after a resize. It now
raises a clear ValueError at parse time, matching the format 3 grid.
- Rectilinear grids had no creation-time spelling for a zero-length axis:
normalize_chunks_1d required sum(edges) == span, which no list of positive
edges can satisfy for span 0, even though the same state is reachable via
resize((0,)) and round-trips through reopen. For span == 0 any non-empty
list of positive edges is now accepted verbatim, producing the same
VaryingDimension(edges, extent=0) that resize produces; the strict sum
check is kept for span > 0.
Tests: the per-spelling regression test from zarr-developers#4328 is replaced by one matrix
over {-1, False, "auto", 1, (1,...), [[2, 2]]} x {(0,), (0, 4), (4, 0),
(0, 0), ()} x {v2, v3} x {no shards, shards="auto" with and without a byte
budget, explicit shards}, with separate small tests for each error case.
Tests that constructed FixedDimension(size=0) now assert it raises, and a
zero-extent test covers the behaviour the old special cases were guarding.
Assisted-by: ClaudeCode:claude-fable-5-11 parent 10f8abe commit cd7d264
7 files changed
Lines changed: 284 additions & 123 deletions
File tree
- changes
- docs/user-guide
- src/zarr/core
- metadata
- tests
- test_metadata
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
708 | 708 | | |
709 | 709 | | |
710 | 710 | | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
711 | 717 | | |
712 | 718 | | |
713 | 719 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | | - | |
| 48 | + | |
49 | 49 | | |
50 | | - | |
51 | | - | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
52 | 57 | | |
53 | 58 | | |
54 | 59 | | |
55 | 60 | | |
56 | | - | |
57 | | - | |
| 61 | + | |
| 62 | + | |
58 | 63 | | |
59 | 64 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 65 | + | |
64 | 66 | | |
65 | 67 | | |
66 | 68 | | |
| |||
69 | 71 | | |
70 | 72 | | |
71 | 73 | | |
72 | | - | |
73 | | - | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
98 | | - | |
99 | | - | |
100 | 98 | | |
101 | 99 | | |
102 | 100 | | |
| |||
110 | 108 | | |
111 | 109 | | |
112 | 110 | | |
113 | | - | |
114 | | - | |
115 | 111 | | |
116 | 112 | | |
117 | 113 | | |
| |||
640 | 636 | | |
641 | 637 | | |
642 | 638 | | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
643 | 653 | | |
644 | 654 | | |
645 | 655 | | |
| |||
677 | 687 | | |
678 | 688 | | |
679 | 689 | | |
680 | | - | |
| 690 | + | |
681 | 691 | | |
682 | 692 | | |
683 | | - | |
684 | | - | |
| 693 | + | |
685 | 694 | | |
686 | 695 | | |
687 | 696 | | |
| |||
724 | 733 | | |
725 | 734 | | |
726 | 735 | | |
727 | | - | |
| 736 | + | |
| 737 | + | |
728 | 738 | | |
729 | 739 | | |
730 | 740 | | |
731 | 741 | | |
732 | 742 | | |
733 | 743 | | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
734 | 751 | | |
735 | 752 | | |
736 | 753 | | |
| |||
741 | 758 | | |
742 | 759 | | |
743 | 760 | | |
744 | | - | |
745 | | - | |
746 | | - | |
| 761 | + | |
747 | 762 | | |
748 | 763 | | |
749 | 764 | | |
| |||
768 | 783 | | |
769 | 784 | | |
770 | 785 | | |
771 | | - | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
772 | 789 | | |
773 | 790 | | |
774 | 791 | | |
| |||
809 | 826 | | |
810 | 827 | | |
811 | 828 | | |
812 | | - | |
| 829 | + | |
813 | 830 | | |
814 | 831 | | |
815 | 832 | | |
| |||
864 | 881 | | |
865 | 882 | | |
866 | 883 | | |
867 | | - | |
868 | | - | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
869 | 888 | | |
870 | 889 | | |
871 | 890 | | |
| |||
886 | 905 | | |
887 | 906 | | |
888 | 907 | | |
889 | | - | |
890 | | - | |
| 908 | + | |
| 909 | + | |
891 | 910 | | |
892 | 911 | | |
893 | 912 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
92 | 99 | | |
93 | 100 | | |
94 | 101 | | |
| |||
0 commit comments