Skip to content

Commit d40dd30

Browse files
committed
fixup
1 parent 31c831d commit d40dd30

File tree

11 files changed

+1247
-729
lines changed

11 files changed

+1247
-729
lines changed

src/zarr/core/array.py

Lines changed: 33 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4744,15 +4744,8 @@ async def init_array(
47444744
sub_codecs = cast("tuple[Codec, ...]", (*array_array, array_bytes, *bytes_bytes))
47454745
codecs_out: tuple[Codec, ...]
47464746

4747-
# Validate that RectilinearChunkGrid is not used with sharding
4748-
if shard_shape_parsed is not None and chunk_grid is not None:
4749-
from zarr.core.chunk_grids import RectilinearChunkGrid
4750-
4751-
if isinstance(chunk_grid, RectilinearChunkGrid):
4752-
raise ValueError(
4753-
"Sharding is not supported with RectilinearChunkGrid (variable-sized chunks). "
4754-
"Use RegularChunkGrid (uniform chunks) with sharding, or use RectilinearChunkGrid without sharding."
4755-
)
4747+
# Note: RectilinearChunkGrid + sharding validation is now handled in resolve_chunk_spec()
4748+
# which is called in create_array() before calling init_array()
47564749

47574750
if shard_shape_parsed is not None:
47584751
index_location = None
@@ -4941,73 +4934,44 @@ async def create_array(
49414934
>>> fill_value=0)
49424935
<AsyncArray memory://140349042942400 shape=(100, 100) dtype=int32>
49434936
"""
4944-
# Handle chunks as ChunkGrid or nested sequence - convert to chunk_grid for init_array
4945-
chunk_grid: ChunkGrid | None = None
4946-
4947-
if isinstance(chunks, ChunkGrid):
4948-
chunk_grid = chunks
4949-
chunks = "auto" # Will be ignored since chunk_grid is set
4950-
elif chunks != "auto" and not isinstance(chunks, (tuple, int)):
4951-
# Check if it's a nested sequence for RectilinearChunkGrid
4952-
# We need to distinguish between flat sequences like [10, 10] and nested like [[10, 20], [5, 5]]
4953-
is_nested = False
4954-
try:
4955-
# Try to iterate and check if elements are sequences
4956-
if hasattr(chunks, "__iter__") and not isinstance(chunks, (str, bytes)): # type: ignore[unreachable]
4957-
first_elem = next(iter(chunks), None)
4958-
if (
4959-
first_elem is not None
4960-
and hasattr(first_elem, "__iter__")
4961-
and not isinstance(first_elem, (str, bytes, int))
4962-
):
4963-
is_nested = True
4964-
except (TypeError, StopIteration):
4965-
pass
4937+
data_parsed, shape_param, dtype_parsed = _parse_data_params(data=data, shape=shape, dtype=dtype)
49664938

4967-
if is_nested:
4968-
# It's a nested sequence - create RectilinearChunkGrid
4969-
from zarr.core.chunk_grids import RectilinearChunkGrid
4939+
# Parse shape to tuple for resolve_chunk_spec
4940+
shape_parsed = parse_shapelike(shape_param)
49704941

4971-
if zarr_format == 2:
4972-
raise ValueError(
4973-
"Variable chunks (nested sequences) are only supported in Zarr format 3. "
4974-
"Use zarr_format=3 or provide a regular tuple for chunks."
4975-
)
4942+
# Parse dtype to get item_size for chunk grid parsing
4943+
# Ensure zarr_format is not None for resolve_chunk_spec
4944+
zarr_format_resolved: ZarrFormat = zarr_format or 3
4945+
zdtype = parse_dtype(dtype_parsed, zarr_format=zarr_format_resolved)
4946+
item_size = 1
4947+
if isinstance(zdtype, HasItemSize):
4948+
item_size = zdtype.item_size
49764949

4977-
try:
4978-
# Convert nested sequence to list of lists for RectilinearChunkGrid
4979-
chunk_shapes = [list(dim) for dim in chunks]
4980-
chunk_grid = RectilinearChunkGrid(chunk_shapes=chunk_shapes)
4981-
chunks = "auto" # Will be ignored since chunk_grid is set
4982-
except (TypeError, ValueError) as e:
4983-
raise TypeError(
4984-
f"Invalid chunks argument: {chunks}. "
4985-
"Expected a tuple of integers, a nested sequence for variable chunks, "
4986-
f"a ChunkGrid instance, or 'auto'. Got error: {e}"
4987-
) from e
4988-
# else: it's a flat sequence like [10, 10] or single int, let it pass through to existing code
4989-
4990-
data_parsed, shape_parsed, dtype_parsed = _parse_data_params(
4991-
data=data, shape=shape, dtype=dtype
4950+
# Resolve chunk specification using consolidated function
4951+
# This handles all validation and returns resolved chunks, shards, and chunk_grid
4952+
from zarr.core.chunk_grids import resolve_chunk_spec
4953+
4954+
resolved = resolve_chunk_spec(
4955+
chunks=chunks,
4956+
shards=shards,
4957+
shape=shape_parsed,
4958+
dtype_itemsize=item_size,
4959+
zarr_format=zarr_format_resolved,
4960+
has_data=data_parsed is not None,
49924961
)
4993-
if data_parsed is not None:
4994-
# from_array doesn't support ChunkGrid parameter, so error if chunk_grid was set
4995-
if chunk_grid is not None:
4996-
raise ValueError(
4997-
"Cannot use ChunkGrid or nested sequences for chunks when creating array from data. "
4998-
"Use a regular tuple for chunks instead."
4999-
)
5000-
# At this point, chunks must be Literal["auto"] | tuple[int, ...] since chunk_grid is None
5001-
from typing import cast
50024962

5003-
chunks_narrowed = cast("Literal['auto', 'keep'] | tuple[int, ...]", chunks)
4963+
chunks_param = resolved.chunks
4964+
shards_param = resolved.shards
4965+
chunk_grid_param = resolved.chunk_grid
4966+
4967+
if data_parsed is not None:
50044968
return await from_array(
50054969
store,
50064970
data=data_parsed,
50074971
write_data=write_data,
50084972
name=name,
5009-
chunks=chunks_narrowed,
5010-
shards=shards,
4973+
chunks=chunks_param,
4974+
shards=shards_param,
50114975
filters=filters,
50124976
compressors=compressors,
50134977
serializer=serializer,
@@ -5027,16 +4991,12 @@ async def create_array(
50274991
store_path = await make_store_path(
50284992
store, path=name, mode=mode, storage_options=storage_options
50294993
)
5030-
# At this point, chunks must be Literal["auto"] | tuple[int, ...] since we set it to "auto" when chunk_grid is set
5031-
from typing import cast
5032-
5033-
chunks_narrowed = cast("tuple[int, ...] | Literal['auto']", chunks)
50344994
return await init_array(
50354995
store_path=store_path,
50364996
shape=shape_parsed,
50374997
dtype=dtype_parsed,
5038-
chunks=chunks_narrowed,
5039-
shards=shards,
4998+
chunks=chunks_param,
4999+
shards=shards_param,
50405000
filters=filters,
50415001
compressors=compressors,
50425002
serializer=serializer,
@@ -5048,7 +5008,7 @@ async def create_array(
50485008
dimension_names=dimension_names,
50495009
overwrite=overwrite,
50505010
config=config,
5051-
chunk_grid=chunk_grid,
5011+
chunk_grid=chunk_grid_param,
50525012
)
50535013

50545014

0 commit comments

Comments
 (0)