@@ -267,35 +267,105 @@ def __eq__(self, other: object) -> bool:
267267StoreLike : TypeAlias = Store | StorePath | FSMap | Path | str | dict [str , Buffer ]
268268
269269
270- async def make_store_path (
270+ async def make_store (
271271 store_like : StoreLike | None ,
272272 * ,
273- path : str | None = "" ,
274273 mode : AccessModeLiteral | None = None ,
275274 storage_options : dict [str , Any ] | None = None ,
276- ) -> StorePath :
275+ ) -> Store :
277276 """
278- Convert a `StoreLike` object into a StorePath object.
277+ Convert a `StoreLike` object into a Store object.
278+
279+ `StoreLike` objects are converted to `Store` as follows:
280+
281+ - `Store` or `StorePath` = `Store` object.
282+ - `Path` or `str` = `LocalStore` object.
283+ - `str` that starts with a protocol = `FsspecStore` object.
284+ - `dict[str, Buffer]` = `MemoryStore` object.
285+ - `None` = `MemoryStore` object.
286+ - `FSMap` = `FsspecStore` object.
287+
288+ Parameters
289+ ----------
290+ store_like : StoreLike | None
291+ The object to convert to a `Store` object.
292+ mode : StoreAccessMode | None, optional
293+ The mode to use when creating the `Store` object. If None, the
294+ default mode is 'r'.
295+ storage_options : dict[str, Any] | None, optional
296+ The storage options to use when creating the `RemoteStore` object. If
297+ None, the default storage options are used.
298+
299+ Returns
300+ -------
301+ Store
302+ The converted Store object.
303+
304+ Raises
305+ ------
306+ TypeError
307+ If the StoreLike object is not one of the supported types, or if storage_options is provided but not used.
308+ ValueError
309+ If storage_options is provided for a store that does not support it.
310+ """
311+ from zarr .storage ._fsspec import FsspecStore # circular import
279312
280- This function takes a `StoreLike` object and returns a `StorePath` object. The
281- `StoreLike` object can be a `Store`, `StorePath`, `Path`, `str`, or `dict[str, Buffer]`.
282- If the `StoreLike` object is a Store or `StorePath`, it is converted to a
283- `StorePath` object. If the `StoreLike` object is a Path or str, it is converted
284- to a LocalStore object and then to a `StorePath` object. If the `StoreLike`
285- object is a dict[str, Buffer], it is converted to a `MemoryStore` object and
286- then to a `StorePath` object.
313+ used_storage_options = False
314+ assert mode in (None , "r" , "r+" , "a" , "w" , "w-" )
315+
316+ # if mode 'r' was provided, we'll open any new stores as read-only
317+ _read_only = mode == "r"
287318
288- If the `StoreLike` object is None, a `MemoryStore` object is created and
289- converted to a `StorePath` object.
319+ if isinstance (store_like , StorePath ):
320+ store = store_like .store
321+ elif isinstance (store_like , Store ):
322+ store = store_like
323+ elif store_like is None :
324+ store = await MemoryStore .open (read_only = _read_only )
325+ elif isinstance (store_like , Path ):
326+ store = await LocalStore .open (root = store_like , read_only = _read_only )
327+ elif isinstance (store_like , str ):
328+ storage_options = storage_options or {}
329+
330+ if _is_fsspec_uri (store_like ):
331+ used_storage_options = True
332+ store = FsspecStore .from_url (
333+ store_like , storage_options = storage_options , read_only = _read_only
334+ )
335+ else :
336+ store = await LocalStore .open (root = Path (store_like ), read_only = _read_only )
337+ elif isinstance (store_like , dict ):
338+ # We deliberate only consider dict[str, Buffer] here, and not arbitrary mutable mappings.
339+ # By only allowing dictionaries, which are in-memory, we know that MemoryStore appropriate.
340+ store = await MemoryStore .open (store_dict = store_like , read_only = _read_only )
341+ elif _has_fsspec and isinstance (store_like , FSMap ):
342+ if storage_options :
343+ raise ValueError (
344+ "'storage_options was provided but is not used for FSMap store_like objects. Specify the storage options when creating the FSMap instance instead."
345+ )
346+ store = FsspecStore .from_mapper (store_like , read_only = _read_only )
347+ else :
348+ raise TypeError (f"Unsupported type for store_like: '{ type (store_like ).__name__ } '" )
290349
291- If the `StoreLike` object is a str and starts with a protocol, it is
292- converted to a RemoteStore object and then to a `StorePath` object.
350+ if storage_options and not used_storage_options :
351+ msg = "'storage_options' was provided but unused. 'storage_options' is only used for fsspec filesystem stores."
352+ raise TypeError (msg )
293353
294- If the `StoreLike` object is a dict[str, Buffer] and the mode is not None,
295- the `MemoryStore` object is created with the given mode.
354+ return store
296355
297- If the `StoreLike` object is a str and starts with a protocol, the
298- RemoteStore object is created with the given mode and storage options.
356+
357+ async def make_store_path (
358+ store_like : StoreLike | None ,
359+ * ,
360+ path : str | None = "" ,
361+ mode : AccessModeLiteral | None = None ,
362+ storage_options : dict [str , Any ] | None = None ,
363+ ) -> StorePath :
364+ """
365+ Convert a `StoreLike` object into a StorePath object.
366+
367+ This function takes a `StoreLike` object and returns a `StorePath` object. See `make_store` for details
368+ of which `Store` is used for each type of `store_like` object.
299369
300370 Parameters
301371 ----------
@@ -319,58 +389,28 @@ async def make_store_path(
319389 Raises
320390 ------
321391 TypeError
322- If the StoreLike object is not one of the supported types.
323- """
324- from zarr . storage . _fsspec import FsspecStore # circular import
392+ If the StoreLike object is not one of the supported types, or if storage_options is provided but not used .
393+ ValueError
394+ If storage_options is provided for a store that does not support it.
325395
326- used_storage_options = False
396+ See Also
397+ --------
398+ make_store
399+ """
327400 path_normalized = normalize_path (path )
401+
328402 if isinstance (store_like , StorePath ):
329- result = store_like / path_normalized
403+ if storage_options :
404+ msg = "'storage_options' was provided but unused. 'storage_options' is only used for fsspec filesystem stores."
405+ raise TypeError (msg )
406+ return store_like / path_normalized
407+ elif _has_fsspec and isinstance (store_like , FSMap ) and path :
408+ raise ValueError (
409+ "'path' was provided but is not used for FSMap store_like objects. Specify the path when creating the FSMap instance instead."
410+ )
330411 else :
331- assert mode in (None , "r" , "r+" , "a" , "w" , "w-" )
332- # if mode 'r' was provided, we'll open any new stores as read-only
333- _read_only = mode == "r"
334- if isinstance (store_like , Store ):
335- store = store_like
336- elif store_like is None :
337- store = await MemoryStore .open (read_only = _read_only )
338- elif isinstance (store_like , Path ):
339- store = await LocalStore .open (root = store_like , read_only = _read_only )
340- elif isinstance (store_like , str ):
341- storage_options = storage_options or {}
342-
343- if _is_fsspec_uri (store_like ):
344- used_storage_options = True
345- store = FsspecStore .from_url (
346- store_like , storage_options = storage_options , read_only = _read_only
347- )
348- else :
349- store = await LocalStore .open (root = Path (store_like ), read_only = _read_only )
350- elif isinstance (store_like , dict ):
351- # We deliberate only consider dict[str, Buffer] here, and not arbitrary mutable mappings.
352- # By only allowing dictionaries, which are in-memory, we know that MemoryStore appropriate.
353- store = await MemoryStore .open (store_dict = store_like , read_only = _read_only )
354- elif _has_fsspec and isinstance (store_like , FSMap ):
355- if path :
356- raise ValueError (
357- "'path' was provided but is not used for FSMap store_like objects. Specify the path when creating the FSMap instance instead."
358- )
359- if storage_options :
360- raise ValueError (
361- "'storage_options was provided but is not used for FSMap store_like objects. Specify the storage options when creating the FSMap instance instead."
362- )
363- store = FsspecStore .from_mapper (store_like , read_only = _read_only )
364- else :
365- raise TypeError (f"Unsupported type for store_like: '{ type (store_like ).__name__ } '" )
366-
367- result = await StorePath .open (store , path = path_normalized , mode = mode )
368-
369- if storage_options and not used_storage_options :
370- msg = "'storage_options' was provided but unused. 'storage_options' is only used for fsspec filesystem stores."
371- raise TypeError (msg )
372-
373- return result
412+ store = await make_store (store_like , mode = mode , storage_options = storage_options )
413+ return await StorePath .open (store , path = path_normalized , mode = mode )
374414
375415
376416def _is_fsspec_uri (uri : str ) -> bool :
0 commit comments