Skip to content

Commit f57f430

Browse files
committed
bubble zarr_format up
1 parent 410e22a commit f57f430

File tree

6 files changed

+540
-67
lines changed

6 files changed

+540
-67
lines changed

src/zarr/api/asynchronous.py

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async def consolidate_metadata(
207207
consolidated metadata, this function raises a `TypeError`.
208208
See ``Store.supports_consolidated_metadata``.
209209
"""
210-
store_path = await make_store_path(store, path=path)
210+
store_path, _ = await make_store_path(store, path=path)
211211

212212
if not store_path.store.supports_consolidated_metadata:
213213
store_name = type(store_path.store).__name__
@@ -346,7 +346,13 @@ async def open(
346346
mode = "r"
347347
else:
348348
mode = "a"
349-
store_path = await make_store_path(store, mode=mode, path=path, storage_options=storage_options)
349+
store_path, url_format = await make_store_path(
350+
store, mode=mode, path=path, storage_options=storage_options
351+
)
352+
353+
# Use URL format if user didn't specify
354+
if zarr_format is None:
355+
zarr_format = url_format
350356

351357
# TODO: the mode check below seems wrong!
352358
if "shape" not in kwargs and mode in {"a", "r", "r+", "w"}:
@@ -450,15 +456,20 @@ async def save_array(
450456
**kwargs
451457
Passed through to :func:`create`, e.g., compressor.
452458
"""
453-
zarr_format = (
454-
_handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
455-
or _default_zarr_format()
456-
)
459+
zarr_format = _handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
460+
457461
if not isinstance(arr, NDArrayLike):
458462
raise TypeError("arr argument must be numpy or other NDArrayLike array")
459463

460464
mode = kwargs.pop("mode", "a")
461-
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
465+
store_path, url_format = await make_store_path(
466+
store, path=path, mode=mode, storage_options=storage_options
467+
)
468+
469+
# Use URL format if user didn't specify, otherwise fall back to default
470+
if zarr_format is None:
471+
zarr_format = url_format or _default_zarr_format()
472+
462473
if np.isscalar(arr):
463474
arr = np.array(arr)
464475
shape = arr.shape
@@ -506,7 +517,9 @@ async def save_group(
506517
NumPy arrays with data to save.
507518
"""
508519

509-
store_path = await make_store_path(store, path=path, mode="w", storage_options=storage_options)
520+
store_path, _ = await make_store_path(
521+
store, path=path, mode="w", storage_options=storage_options
522+
)
510523

511524
zarr_format = (
512525
_handle_zarr_version_or_format(
@@ -725,12 +738,15 @@ async def create_group(
725738
The new group.
726739
"""
727740

728-
if zarr_format is None:
729-
zarr_format = _default_zarr_format()
730-
731741
mode: Literal["a"] = "a"
732742

733-
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
743+
store_path, url_format = await make_store_path(
744+
store, path=path, mode=mode, storage_options=storage_options
745+
)
746+
747+
# Use URL format if user didn't specify, otherwise fall back to default
748+
if zarr_format is None:
749+
zarr_format = url_format or _default_zarr_format()
734750

735751
return await AsyncGroup.from_store(
736752
store=store_path,
@@ -828,7 +844,14 @@ async def open_group(
828844
if chunk_store is not None:
829845
warnings.warn("chunk_store is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
830846

831-
store_path = await make_store_path(store, mode=mode, storage_options=storage_options, path=path)
847+
store_path, url_format = await make_store_path(
848+
store, mode=mode, storage_options=storage_options, path=path
849+
)
850+
851+
# Use URL format if user didn't specify
852+
if zarr_format is None:
853+
zarr_format = url_format
854+
832855
if attributes is None:
833856
attributes = {}
834857

@@ -999,10 +1022,7 @@ async def create(
9991022
z : array
10001023
The array.
10011024
"""
1002-
zarr_format = (
1003-
_handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
1004-
or _default_zarr_format()
1005-
)
1025+
zarr_format = _handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
10061026

10071027
if synchronizer is not None:
10081028
warnings.warn("synchronizer is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
@@ -1025,7 +1045,13 @@ async def create(
10251045
mode = kwargs.pop("mode", None)
10261046
if mode is None:
10271047
mode = "a"
1028-
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
1048+
store_path, url_format = await make_store_path(
1049+
store, path=path, mode=mode, storage_options=storage_options
1050+
)
1051+
1052+
# Use URL format if user didn't specify, otherwise fall back to default
1053+
if zarr_format is None:
1054+
zarr_format = url_format or _default_zarr_format()
10291055

10301056
config_parsed = parse_array_config(config)
10311057

@@ -1236,10 +1262,16 @@ async def open_array(
12361262
"""
12371263

12381264
mode = kwargs.pop("mode", None)
1239-
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
1265+
store_path, url_format = await make_store_path(
1266+
store, path=path, mode=mode, storage_options=storage_options
1267+
)
12401268

12411269
zarr_format = _handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
12421270

1271+
# Use URL format if user didn't specify
1272+
if zarr_format is None:
1273+
zarr_format = url_format
1274+
12431275
if "write_empty_chunks" in kwargs:
12441276
_warn_write_empty_chunks_kwarg()
12451277

src/zarr/core/array.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ async def _create(
637637
"""
638638

639639
dtype_parsed = parse_dtype(dtype, zarr_format=zarr_format)
640-
store_path = await make_store_path(store)
640+
store_path, _ = await make_store_path(store)
641641

642642
shape = parse_shapelike(shape)
643643

@@ -976,7 +976,7 @@ async def open(
976976
>>> async_arr = await AsyncArray.open(store) # doctest: +ELLIPSIS
977977
<AsyncArray memory://... shape=(100, 100) dtype=int32>
978978
"""
979-
store_path = await make_store_path(store)
979+
store_path, _ = await make_store_path(store)
980980
metadata_dict = await get_array_metadata(store_path, zarr_format=zarr_format)
981981
# TODO: remove this cast when we have better type hints
982982
_metadata_dict = cast("ArrayV3MetadataDict", metadata_dict)
@@ -4351,7 +4351,9 @@ async def from_array(
43514351
"""
43524352
mode: Literal["a"] = "a"
43534353
config_parsed = parse_array_config(config)
4354-
store_path = await make_store_path(store, path=name, mode=mode, storage_options=storage_options)
4354+
store_path, _ = await make_store_path(
4355+
store, path=name, mode=mode, storage_options=storage_options
4356+
)
43554357

43564358
(
43574359
chunks,
@@ -4809,7 +4811,7 @@ async def create_array(
48094811
else:
48104812
mode: Literal["a"] = "a"
48114813

4812-
store_path = await make_store_path(
4814+
store_path, _ = await make_store_path(
48134815
store, path=name, mode=mode, storage_options=storage_options
48144816
)
48154817
return await init_array(

src/zarr/core/group.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ async def from_store(
463463
overwrite: bool = False,
464464
zarr_format: ZarrFormat = 3,
465465
) -> AsyncGroup:
466-
store_path = await make_store_path(store)
466+
store_path, _ = await make_store_path(store)
467467

468468
if overwrite:
469469
if store_path.store.supports_deletes:
@@ -511,7 +511,7 @@ async def open(
511511
(``.zmetadata`` by default). Specify the custom key as ``use_consolidated``
512512
to load consolidated metadata from a non-default key.
513513
"""
514-
store_path = await make_store_path(store)
514+
store_path, _ = await make_store_path(store)
515515
if not store_path.store.supports_consolidated_metadata:
516516
# Fail if consolidated metadata was requested but the Store doesn't support it
517517
if use_consolidated:

src/zarr/storage/_common.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ async def make_store_path(
269269
path: str | None = "",
270270
mode: AccessModeLiteral | None = None,
271271
storage_options: dict[str, Any] | None = None,
272-
) -> StorePath:
272+
) -> tuple[StorePath, ZarrFormat | None]:
273273
"""
274274
Convert a `StoreLike` object into a StorePath object.
275275
@@ -309,8 +309,9 @@ async def make_store_path(
309309
310310
Returns
311311
-------
312-
StorePath
313-
The converted StorePath object.
312+
tuple[StorePath, ZarrFormat | None]
313+
The converted StorePath object and the zarr format (2, 3, or None) extracted
314+
from the URL if it was a ZEP 8 URL, otherwise None.
314315
315316
Raises
316317
------
@@ -325,6 +326,7 @@ async def make_store_path(
325326
_read_only = mode == "r"
326327

327328
path_normalized = normalize_path(path)
329+
zarr_format = None # Default: no format specified
328330

329331
# Check if store_like is a ZEP 8 URL
330332
if isinstance(store_like, str) and is_zep8_url(store_like):
@@ -335,11 +337,13 @@ async def make_store_path(
335337
if storage_options:
336338
store_kwargs["storage_options"] = storage_options
337339

338-
# Resolve URL and extract path in a single pass (more efficient than separate calls)
339-
store, url_path = await resolver.resolve_url_with_path(store_like, **store_kwargs)
340+
# Resolve URL and extract path and format in a single pass
341+
store, url_path, zarr_format = await resolver.resolve_url_with_path(
342+
store_like, **store_kwargs
343+
)
340344
combined_path = _combine_paths(url_path, path_normalized)
341345

342-
return await StorePath.open(store, path=combined_path, mode=mode)
346+
return await StorePath.open(store, path=combined_path, mode=mode), zarr_format
343347

344348
if storage_options is not None:
345349
raise TypeError(
@@ -350,7 +354,7 @@ async def make_store_path(
350354

351355
if isinstance(store_like, StorePath):
352356
# Already a StorePath
353-
return store_like / path_normalized
357+
return store_like / path_normalized, None
354358

355359
elif isinstance(store_like, Store):
356360
# Already a Store
@@ -384,7 +388,7 @@ async def make_store_path(
384388
else:
385389
raise TypeError(f"Unsupported type for store_like: '{type(store_like).__name__}'")
386390

387-
return await StorePath.open(store, path=path_normalized, mode=mode)
391+
return await StorePath.open(store, path=path_normalized, mode=mode), None
388392

389393

390394
def _combine_paths(url_path: str, additional_path: str) -> str:

0 commit comments

Comments
 (0)