4343from zarr .core .chunk_grids import (
4444 ChunkGrid ,
4545 ChunksLike ,
46+ ChunksType ,
4647 RegularChunkGrid ,
48+ RegularChunks ,
4749 _auto_partition ,
4850 _normalize_chunks ,
4951 resolve_chunk_spec ,
@@ -1050,20 +1052,33 @@ def shape(self) -> tuple[int, ...]:
10501052 return self .metadata .shape
10511053
10521054 @property
1053- def chunks (self ) -> tuple [ int , ...] | tuple [ tuple [ int , ...], ...] :
1055+ def chunks (self ) -> ChunksType :
10541056 """Returns the chunk specification of the Array.
10551057
1056- For arrays using RegularChunkGrid: returns a tuple of ints representing
1057- the uniform chunk shape. If sharding is used, the inner chunk shape is returned.
1058+ Returns either RegularChunks (for uniform chunk sizes) or RectilinearChunks
1059+ (for variable chunk sizes per dimension). Both types behave like tuples but
1060+ provide richer semantics including named access when dimension_names are available.
10581061
1059- For arrays using RectilinearChunkGrid: returns a tuple of tuples, where
1060- each inner tuple contains the chunk sizes along that dimension (not RLE encoded).
1062+ For arrays using RegularChunkGrid: returns RegularChunks with uniform chunk sizes.
1063+ If sharding is used, the inner chunk shape is returned.
1064+
1065+ For arrays using RectilinearChunkGrid: returns RectilinearChunks where each
1066+ element is a tuple containing the chunk sizes along that dimension (not RLE encoded).
10611067
10621068 Returns
10631069 -------
1064- tuple[int, ...] | tuple[tuple[int, ...], ...]
1065- For regular chunks: (chunk_size_dim0, chunk_size_dim1, ...)
1066- For rectilinear chunks: ((sizes_dim0), (sizes_dim1), ...)
1070+ ChunksType
1071+ RegularChunks for regular chunks or RectilinearChunks for variable chunks
1072+
1073+ Examples
1074+ --------
1075+ >>> arr = zarr.create_array(shape=(100, 200), chunks=(10, 20))
1076+ >>> arr.chunks
1077+ RegularChunks((10, 20))
1078+ >>> isinstance(arr.chunks, RegularChunks)
1079+ True
1080+ >>> tuple(arr.chunks)
1081+ (10, 20)
10671082 """
10681083 return self .metadata .chunks
10691084
@@ -1274,11 +1289,10 @@ def _chunk_grid_shape(self) -> tuple[int, ...]:
12741289 # Handle 0-dimensional arrays
12751290 if len (chunks ) == 0 :
12761291 return ()
1277- # For RegularChunkGrid (or sharded with RegularChunkGrid ), chunks is tuple[int, ...]
1278- if isinstance (chunks [ 0 ], int ):
1292+ # For RegularChunkGrid (or sharded), use RegularChunks type check
1293+ if isinstance (chunks , RegularChunks ):
12791294 return tuple (starmap (ceildiv , zip (self .shape , chunks , strict = True )))
1280- # For RectilinearChunkGrid, chunks is tuple[tuple[int, ...], ...]
1281- # Use the chunk_grid method
1295+ # For RectilinearChunkGrid, use the chunk_grid method
12821296 return self .metadata .chunk_grid .get_chunk_grid_shape (self .shape )
12831297
12841298 @property
@@ -1292,7 +1306,7 @@ def _shard_grid_shape(self) -> tuple[int, ...]:
12921306 The shape of the shard grid for this array.
12931307 """
12941308 if self .shards is None :
1295- shard_shape = self .chunks
1309+ shard_shape : tuple [ int , ...] | ChunksType = self .chunks
12961310 else :
12971311 shard_shape = self .shards
12981312 return tuple (starmap (ceildiv , zip (self .shape , shard_shape , strict = True )))
@@ -5624,16 +5638,15 @@ def _iter_shard_regions(
56245638 If the array uses RectilinearChunkGrid (variable-sized chunks).
56255639 """
56265640 chunks = array .chunks
5627- if chunks and not isinstance (chunks [ 0 ], int ):
5641+ if not isinstance (chunks , RegularChunks ):
56285642 raise NotImplementedError (
56295643 "_iter_shard_regions is not supported for arrays with variable-sized chunks "
56305644 "(RectilinearChunkGrid). Use the chunk_grid API directly for variable chunk access."
56315645 )
56325646
5633- # After the check above, chunks is tuple[int, ...]
5634- regular_chunks = cast (tuple [int , ...], chunks )
5647+ # Type narrowing: chunks is now RegularChunks (subclass of tuple[int, ...])
56355648 if array .shards is None :
5636- shard_shape : Sequence [int ] = regular_chunks
5649+ shard_shape : Sequence [int ] = chunks
56375650 else :
56385651 shard_shape = array .shards
56395652
@@ -5673,17 +5686,16 @@ def _iter_chunk_regions(
56735686 If the array uses RectilinearChunkGrid (variable-sized chunks).
56745687 """
56755688 chunks = array .chunks
5676- if chunks and not isinstance (chunks [ 0 ], int ):
5689+ if not isinstance (chunks , RegularChunks ):
56775690 raise NotImplementedError (
56785691 "_iter_chunk_regions is not supported for arrays with variable-sized chunks "
56795692 "(RectilinearChunkGrid). Use the chunk_grid API directly for variable chunk access."
56805693 )
56815694
5682- # After the check above, chunks is tuple[int, ...]
5683- regular_chunks = cast (tuple [int , ...], chunks )
5695+ # Type narrowing: chunks is now RegularChunks (subclass of tuple[int, ...])
56845696 return _iter_regions (
56855697 array .shape ,
5686- regular_chunks ,
5698+ chunks ,
56875699 origin = origin ,
56885700 selection_shape = selection_shape ,
56895701 trim_excess = True ,
0 commit comments