File tree Expand file tree Collapse file tree 3 files changed +20
-1
lines changed Expand file tree Collapse file tree 3 files changed +20
-1
lines changed Original file line number Diff line number Diff line change 1+ Suppress `FileNotFoundError ` when deleting non-existent keys in the `obstore ` adapter.
2+
3+ When writing empty chunks (i.e. chunks where all values are equal to the array's fill value) to a zarr array, zarr
4+ will delete those chunks from the underlying store. For zarr arrays backed by the `obstore ` adapter, this will potentially
5+ raise a `FileNotFoundError ` if the chunk doesn't already exist.
6+ Since whether or not a delete of a non-existing object raises an error depends on the behavior of the underlying store,
7+ suppressing the error in all cases results in consistent behavior across stores, and is also what `zarr ` seems to expect
8+ from the store.
Original file line number Diff line number Diff line change @@ -181,7 +181,13 @@ async def delete(self, key: str) -> None:
181181 import obstore as obs
182182
183183 self ._check_writable ()
184- await obs .delete_async (self .store , key )
184+
185+ # Some obstore stores such as local filesystems, GCP and Azure raise an error
186+ # when deleting a non-existent key, while others such as S3 and in-memory do
187+ # not. We suppress the error to make the behavior consistent across all obstore
188+ # stores. This is also in line with the behavior of the other Zarr store adapters.
189+ with contextlib .suppress (FileNotFoundError ):
190+ await obs .delete_async (self .store , key )
185191
186192 @property
187193 def supports_partial_writes (self ) -> bool :
Original file line number Diff line number Diff line change @@ -349,6 +349,11 @@ async def test_delete_dir(self, store: S) -> None:
349349 assert not await store .exists ("foo/zarr.json" )
350350 assert not await store .exists ("foo/c/0" )
351351
352+ async def test_delete_nonexistent_key_does_not_raise (self , store : S ) -> None :
353+ if not store .supports_deletes :
354+ pytest .skip ("store does not support deletes" )
355+ await store .delete ("nonexistent_key" )
356+
352357 async def test_is_empty (self , store : S ) -> None :
353358 assert await store .is_empty ("" )
354359 await self .set (
You can’t perform that action at this time.
0 commit comments