zarr-python icon indicating copy to clipboard operation
zarr-python copied to clipboard

[v3] `zarr.save` - AttributeError: 'str' object has no attribute 'shape'

Open jhamman opened this issue 1 year ago • 4 comments

Zarr version

3.0.0.beta

Numcodecs version

0.13

Python Version

3.11

Operating System

Mac

Installation

pip

Description

zarr.save is failing to do something basic that works fine in 2.18.3.

Steps to reproduce

In [9]: a = np.arange(10)

In [10]: zarr.save('data/example.zarr', a, mode='w')
--------------------------------------------------------------------------
AttributeError                           Traceback (most recent call last)
Cell In[10], line 1
----> 1 zarr.save('data/example.zarr', a, mode='w')

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/api/synchronous.py:107, in save(store, zarr_version, zarr_format, path, *args, **kwargs)
     99 def save(
    100     store: StoreLike,
    101     *args: NDArrayLike,
   (...)
    105     **kwargs: Any,  # TODO: type kwargs as valid args to async_api.save
    106 ) -> None:
--> 107     return sync(
    108         async_api.save(
    109             store, *args, zarr_version=zarr_version, zarr_format=zarr_format, path=path, **kwargs
    110         )
    111     )

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/core/sync.py:141, in sync(coro, loop, timeout)
    138 return_result = next(iter(finished)).result()
    140 if isinstance(return_result, BaseException):
--> 141     raise return_result
    142 else:
    143     return return_result

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/core/sync.py:100, in _runner(coro)
     95 """
     96 Await a coroutine and return the result of running it. If awaiting the coroutine raises an
     97 exception, the exception will be returned.
     98 """
     99 try:
--> 100     return await coro
    101 except Exception as ex:
    102     return ex

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/api/asynchronous.py:368, in save(store, zarr_version, zarr_format, path, *args, **kwargs)
    366     await save_array(store, args[0], zarr_format=zarr_format, path=path)
    367 else:
--> 368     await save_group(store, *args, zarr_format=zarr_format, path=path, **kwargs)

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/api/asynchronous.py:476, in save_group(store, zarr_version, zarr_format, path, storage_options, *args, **kwargs)
    470     _path = f"{path}/{k}" if path is not None else k
    471     aws.append(
    472         save_array(
    473             store, arr, zarr_format=zarr_format, path=_path, storage_options=storage_options
    474         )
    475     )
--> 476 await asyncio.gather(*aws)

File ~/miniforge3/envs/icechunk-demo/lib/python3.12/site-packages/zarr/api/asynchronous.py:412, in save_array(store, arr, zarr_version, zarr_format, path, storage_options, **kwargs)
    407 if path is not None:
    408     store_path = store_path / path
    409 new = await AsyncArray.create(
    410     store_path,
    411     zarr_format=zarr_format,
--> 412     shape=arr.shape,
    413     dtype=arr.dtype,
    414     chunks=arr.shape,
    415     **kwargs,
    416 )
    417 await new.setitem(slice(None), arr)

AttributeError: 'str' object has no attribute 'shape'

Additional output

No response

jhamman avatar Oct 18 '24 19:10 jhamman

zarr.save does not have an argument mode. All arguments apart from store, zarr_version, zarr_format and path will get interpreted as numpy arrays. Without the mode argument zarr.save works. Is zarr.save expected to accept a mode?

brokkoli71 avatar Oct 23 '24 17:10 brokkoli71

Good call! Based on the discussion in #2359, I think we may not need to add this mode argument then. In 2.18, we don't have a mode argument:

https://github.com/zarr-developers/zarr-python/blob/support/v2/zarr/convenience.py#L287

And if we move to mode only being r or w, then the mode for zarr.save is obviously w.

jhamman avatar Oct 23 '24 19:10 jhamman

👍🏼 I would suggest adding a check if all args, kwargs are np.ndarray. And if not raising a useful error

brokkoli71 avatar Oct 23 '24 20:10 brokkoli71

That sounds great!

jhamman avatar Oct 23 '24 20:10 jhamman