1414from hypothesis import strategies as st
1515
1616from zarr_metadata .testing ._strategy import ChunkGridStrategy
17- from zarr_metadata .v3 .chunk_grid .rectilinear import RECTILINEAR_CHUNK_GRID
18- from zarr_metadata .v3 .chunk_grid .regular import REGULAR_CHUNK_GRID
17+ from zarr_metadata .v3 .chunk_grid .rectilinear import (
18+ RECTILINEAR_CHUNK_GRID ,
19+ RectilinearChunkGridConfiguration ,
20+ RectilinearDimSpec ,
21+ )
22+ from zarr_metadata .v3 .chunk_grid .regular import REGULAR_CHUNK_GRID , RegularChunkGridConfiguration
1923
2024if TYPE_CHECKING :
2125 from collections .abc import Mapping
2226
23- from zarr_metadata ._common import JSONValue
2427 from zarr_metadata .testing ._strategy import Strategies
2528 from zarr_metadata .v3 ._definition import ChunkGridDefinition
2629
@@ -46,24 +49,24 @@ def _length(extent: int | None) -> st.SearchStrategy[int]:
4649
4750def _regular (
4851 shape : tuple [int , ...] | None , _strategies : Strategies
49- ) -> st .SearchStrategy [Mapping [ str , JSONValue ] ]:
52+ ) -> st .SearchStrategy [RegularChunkGridConfiguration ]:
5053 """A chunk length for each dimension."""
5154 if shape is None :
5255 lengths = st .lists (_length (None ), max_size = _MAX_RANK ).map (tuple )
5356 else :
5457 lengths = st .tuples (* (_length (extent ) for extent in shape ))
55- return lengths .map (lambda chunk_shape : { " chunk_shape" : chunk_shape } )
58+ return lengths .map (lambda chunk_shape : RegularChunkGridConfiguration ( chunk_shape = chunk_shape ) )
5659
5760
58- def _spelled_run (draw : st .DrawFn , size : int , count : int ) -> list [JSONValue ]:
61+ def _spelled_run (draw : st .DrawFn , size : int , count : int ) -> list [int | tuple [ int , int ] ]:
5962 """`count` chunks of `size`: one `[size, count]` pair, or the size written once for each."""
6063 if draw (st .booleans ()):
6164 return [(size , count )]
6265 return [size ] * count
6366
6467
6568@st .composite
66- def _edges (draw : st .DrawFn , extent : int | None ) -> JSONValue :
69+ def _edges (draw : st .DrawFn , extent : int | None ) -> tuple [ int | tuple [ int , int ], ...] :
6770 """Edge lengths along a dimension, covering `extent`, in runs spelled as pairs or written out.
6871
6972 Runs are drawn apart, so two of one size can sit side by side and a
@@ -81,26 +84,30 @@ def _edges(draw: st.DrawFn, extent: int | None) -> JSONValue:
8184 covered = sum (size * count for size , count in runs )
8285 if extent is not None and covered < extent :
8386 runs .append ((extent - covered , 1 ))
84- spelled : list [JSONValue ] = []
87+ spelled : list [int | tuple [ int , int ] ] = []
8588 for size , count in runs :
8689 spelled .extend (_spelled_run (draw , size , count ))
8790 return tuple (spelled )
8891
8992
90- def _rectilinear_dimension (extent : int | None ) -> st .SearchStrategy [JSONValue ]:
93+ def _rectilinear_dimension (extent : int | None ) -> st .SearchStrategy [RectilinearDimSpec ]:
9194 """A bare length, which repeats until it covers the dimension, or edges that cover it."""
9295 return _length (extent ) | _edges (extent )
9396
9497
9598def _rectilinear (
9699 shape : tuple [int , ...] | None , _strategies : Strategies
97- ) -> st .SearchStrategy [Mapping [ str , JSONValue ] ]:
100+ ) -> st .SearchStrategy [RectilinearChunkGridConfiguration ]:
98101 """Inline chunk shapes, one entry for each dimension."""
99102 if shape is None :
100103 dimensions = st .lists (_rectilinear_dimension (None ), max_size = _MAX_RANK ).map (tuple )
101104 else :
102105 dimensions = st .tuples (* (_rectilinear_dimension (extent ) for extent in shape ))
103- return dimensions .map (lambda chunk_shapes : {"kind" : "inline" , "chunk_shapes" : chunk_shapes })
106+ return dimensions .map (
107+ lambda chunk_shapes : RectilinearChunkGridConfiguration (
108+ kind = "inline" , chunk_shapes = chunk_shapes
109+ )
110+ )
104111
105112
106113CHUNK_GRID_STRATEGIES : Final [Mapping [ChunkGridDefinition [Any ], ChunkGridStrategy ]] = {
0 commit comments