Skip to content

LocalStore doesn't create non-existent directories #2334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TomAugspurger opened this issue Oct 11, 2024 · 1 comment · Fixed by #2337
Closed

LocalStore doesn't create non-existent directories #2334

TomAugspurger opened this issue Oct 11, 2024 · 1 comment · Fixed by #2337
Labels
bug Potential issues with the zarr-python library

Comments

@TomAugspurger
Copy link
Contributor

Zarr version

v3

Numcodecs version

na

Python Version

na

Operating System

na

Installation

na

Description

zarr v3 doesn't create a directory for a LocalStore if it doesn't exist. Should it?

Steps to reproduce

In [3]: zarr.open_group(zarr.storage.LocalStore("/tmp/zarr-python-v3-not-a-directory", mode="w"))
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[3], line 1
----> 1 zarr.open_group(zarr.storage.LocalStore("/tmp/zarr-python-v3-not-a-directory", mode="w"))

File ~/gh/zarr-developers/zarr-python/src/zarr/_compat.py:43, in _deprecate_positional_args.<locals>._inner_deprecate_positional_args.<locals>.inner_f(*args, **kwargs)
     41 extra_args = len(args) - len(all_args)
     42 if extra_args <= 0:
---> 43     return f(*args, **kwargs)
     45 # extra_args > 0
     46 args_msg = [
     47     f"{name}={arg}"
     48     for name, arg in zip(kwonly_args[:extra_args], args[-extra_args:], strict=False)
     49 ]

File ~/gh/zarr-developers/zarr-python/src/zarr/api/synchronous.py:216, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, zarr_format, meta_array, attributes, use_consolidated)
    199 @_deprecate_positional_args
    200 def open_group(
    201     store: StoreLike | None = None,
   (...)
    213     use_consolidated: bool | str | None = None,
    214 ) -> Group:
    215     return Group(
--> 216         sync(
    217             async_api.open_group(
    218                 store=store,
    219                 mode=mode,
    220                 cache_attrs=cache_attrs,
    221                 synchronizer=synchronizer,
    222                 path=path,
    223                 chunk_store=chunk_store,
    224                 storage_options=storage_options,
    225                 zarr_version=zarr_version,
    226                 zarr_format=zarr_format,
    227                 meta_array=meta_array,
    228                 attributes=attributes,
    229                 use_consolidated=use_consolidated,
    230             )
    231         )
    232     )

File ~/gh/zarr-developers/zarr-python/src/zarr/core/sync.py:91, in sync(coro, loop, timeout)
     88 return_result = next(iter(finished)).result()
     90 if isinstance(return_result, BaseException):
---> 91     raise return_result
     92 else:
     93     return return_result

File ~/gh/zarr-developers/zarr-python/src/zarr/core/sync.py:50, in _runner(coro)
     45 """
     46 Await a coroutine and return the result of running it. If awaiting the coroutine raises an
     47 exception, the exception will be returned.
     48 """
     49 try:
---> 50     return await coro
     51 except Exception as ex:
     52     return ex

File ~/gh/zarr-developers/zarr-python/src/zarr/api/asynchronous.py:699, in open_group(store, mode, cache_attrs, synchronizer, path, chunk_store, storage_options, zarr_version, zarr_format, meta_array, attributes, use_consolidated)
    696 if chunk_store is not None:
    697     warnings.warn("chunk_store is not yet implemented", RuntimeWarning, stacklevel=2)
--> 699 store_path = await make_store_path(store, mode=mode, storage_options=storage_options)
    700 if path is not None:
    701     store_path = store_path / path

File ~/gh/zarr-developers/zarr-python/src/zarr/storage/common.py:99, in make_store_path(store_like, mode, storage_options)
     97     if mode is not None and mode != store_like.mode.str:
     98         store_like = store_like.with_mode(mode)
---> 99     await store_like._ensure_open()
    100     result = StorePath(store_like)
    101 elif store_like is None:
    102     # mode = "w" is an exception to the default mode = 'r'

File ~/gh/zarr-developers/zarr-python/src/zarr/abc/store.py:80, in Store._ensure_open(self)
     78 async def _ensure_open(self) -> None:
     79     if not self._is_open:
---> 80         await self._open()

File ~/gh/zarr-developers/zarr-python/src/zarr/abc/store.py:73, in Store._open(self)
     71     raise ValueError("store is already open")
     72 if self.mode.str == "w":
---> 73     await self.clear()
     74 elif self.mode.str == "w-" and not await self.empty():
     75     raise FileExistsError("Store already exists")

File ~/gh/zarr-developers/zarr-python/src/zarr/storage/local.py:98, in LocalStore.clear(self)
     96 async def clear(self) -> None:
     97     self._check_writable()
---> 98     shutil.rmtree(self.root)
     99     self.root.mkdir()

File ~/mambaforge/envs/python=3.12/lib/python3.12/shutil.py:759, in rmtree(path, ignore_errors, onerror, onexc, dir_fd)
    757 try:
    758     while stack:
--> 759         _rmtree_safe_fd(stack, onexc)
    760 finally:
    761     # Close any file descriptors still on the stack.
    762     while stack:

File ~/mambaforge/envs/python=3.12/lib/python3.12/shutil.py:703, in _rmtree_safe_fd(stack, onexc)
    701 except OSError as err:
    702     err.filename = path
--> 703     onexc(func, path, err)

File ~/mambaforge/envs/python=3.12/lib/python3.12/shutil.py:669, in _rmtree_safe_fd(stack, onexc)
    667 assert func is os.lstat
    668 if orig_entry is None:
--> 669     orig_st = os.lstat(name, dir_fd=dirfd)
    670 else:
    671     orig_st = orig_entry.stat(follow_symlinks=False)

FileNotFoundError: [Errno 2] No such file or directory: PosixPath('/tmp/zarr-python-v3-not-a-directory')

In zarr-python 2.x it created the directory:

In [2]: zarr.open_group("/tmp/zarr-python-v2-not-a-directory")
Out[2]: <zarr.hierarchy.Group '/'>

Additional output

No response

@TomAugspurger TomAugspurger added the bug Potential issues with the zarr-python library label Oct 11, 2024
@d-v-b
Copy link
Contributor

d-v-b commented Oct 11, 2024

I think it should!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Potential issues with the zarr-python library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants