Skip to content

Commit c38c2f7

Browse files
committed
respond to review
1 parent d7a6982 commit c38c2f7

File tree

8 files changed

+35
-39
lines changed

8 files changed

+35
-39
lines changed

src/zarr/abc/store.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ def list(self) -> AsyncGenerator[str, None]:
342342
@abstractmethod
343343
def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]:
344344
"""
345-
Retrieve all keys in the store that begin with a given prefix. Keys are returned with the
346-
common leading prefix removed.
345+
Retrieve all keys in the store that begin with a given prefix. Keys are returned as
346+
absolute paths (i.e. including the prefix).
347347
348348
Parameters
349349
----------
@@ -371,7 +371,7 @@ def list_dir(self, prefix: str) -> AsyncGenerator[str, None]:
371371
"""
372372
...
373373

374-
async def delete_dir(self, prefix: str, recursive: bool = True) -> None:
374+
async def delete_dir(self, prefix: str) -> None:
375375
"""
376376
Remove all keys and prefixes in the store that begin with a given prefix.
377377
"""
@@ -380,24 +380,8 @@ async def delete_dir(self, prefix: str, recursive: bool = True) -> None:
380380
if not self.supports_listing:
381381
raise NotImplementedError
382382
self._check_writable()
383-
if recursive:
384-
if not prefix.endswith("/"):
385-
prefix += "/"
386-
async for key in self.list_prefix(prefix):
387-
await self.delete(key)
388-
else:
389-
async for key in self.list_dir(prefix):
390-
await self.delete(f"{prefix}/{key}")
391-
392-
async def delete_prefix(self, prefix: str) -> None:
393-
"""
394-
Remove all keys in the store that begin with a given prefix.
395-
"""
396-
if not self.supports_deletes:
397-
raise NotImplementedError
398-
if not self.supports_listing:
399-
raise NotImplementedError
400-
self._check_writable()
383+
if not prefix.endswith("/"):
384+
prefix += "/"
401385
async for key in self.list_prefix(prefix):
402386
await self.delete(key)
403387

src/zarr/core/array.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ async def _create_v3(
556556
) -> AsyncArray[ArrayV3Metadata]:
557557
if exists_ok:
558558
if store_path.store.supports_deletes:
559-
await store_path.delete_dir(recursive=True)
559+
await store_path.delete_dir()
560560
else:
561561
await ensure_no_existing_node(store_path, zarr_format=3)
562562
else:
@@ -613,7 +613,7 @@ async def _create_v2(
613613
) -> AsyncArray[ArrayV2Metadata]:
614614
if exists_ok:
615615
if store_path.store.supports_deletes:
616-
await store_path.delete_dir(recursive=True)
616+
await store_path.delete_dir()
617617
else:
618618
await ensure_no_existing_node(store_path, zarr_format=2)
619619
else:

src/zarr/core/group.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ async def from_store(
407407

408408
if exists_ok:
409409
if store_path.store.supports_deletes:
410-
await store_path.delete_dir(recursive=True)
410+
await store_path.delete_dir()
411411
else:
412412
await ensure_no_existing_node(store_path, zarr_format=zarr_format)
413413
else:
@@ -717,7 +717,7 @@ def _getitem_consolidated(
717717
async def delitem(self, key: str) -> None:
718718
store_path = self.store_path / key
719719

720-
await store_path.delete_dir(recursive=True)
720+
await store_path.delete_dir()
721721
if self.metadata.consolidated_metadata:
722722
self.metadata.consolidated_metadata.metadata.pop(key, None)
723723
await self._save_metadata()

src/zarr/storage/common.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,14 @@ async def delete(self) -> None:
101101
"""
102102
await self.store.delete(self.path)
103103

104-
async def delete_dir(self, recursive: bool = False) -> None:
104+
async def delete_dir(self) -> None:
105105
"""
106106
Delete all keys with the given prefix from the store.
107107
"""
108-
await self.store.delete_dir(self.path, recursive=recursive)
109-
110-
async def delete_prefix(self) -> None:
111-
"""
112-
Delete all keys with the given prefix from the store.
113-
"""
114-
await self.store.delete_prefix(self.path)
108+
path = self.path
109+
if not path.endswith("/"):
110+
path += "/"
111+
await self.store.delete_dir(path)
115112

116113
async def set_if_not_exists(self, default: Buffer) -> None:
117114
"""

src/zarr/storage/logging.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ async def list_dir(self, prefix: str) -> AsyncGenerator[str, None]:
222222
async for key in self._store.list_dir(prefix=prefix):
223223
yield key
224224

225+
async def delete_dir(self, prefix: str) -> None:
226+
# docstring inherited
227+
with self.log(prefix):
228+
await self._store.delete_dir(prefix=prefix)
229+
225230
def with_mode(self, mode: AccessModeLiteral) -> Self:
226231
# docstring inherited
227232
with self.log(mode):

src/zarr/testing/store.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,24 @@ async def test_exists(self, store: S) -> None:
213213
assert await store.exists("foo/zarr.json")
214214

215215
async def test_delete(self, store: S) -> None:
216+
if not store.supports_deletes:
217+
pytest.skip("store does not support deletes")
216218
await store.set("foo/zarr.json", self.buffer_cls.from_bytes(b"bar"))
217219
assert await store.exists("foo/zarr.json")
218220
await store.delete("foo/zarr.json")
219221
assert not await store.exists("foo/zarr.json")
220222

223+
async def test_delete_dir(self, store: S) -> None:
224+
if not store.supports_deletes:
225+
pytest.skip("store does not support deletes")
226+
await store.set("zarr.json", self.buffer_cls.from_bytes(b"root"))
227+
await store.set("foo/zarr.json", self.buffer_cls.from_bytes(b"bar"))
228+
await store.set("foo/c/0", self.buffer_cls.from_bytes(b"chunk"))
229+
await store.delete_dir("foo")
230+
assert await store.exists("zarr.json")
231+
assert not await store.exists("foo/zarr.json")
232+
assert not await store.exists("foo/c/0")
233+
221234
async def test_empty(self, store: S) -> None:
222235
assert await store.empty()
223236
await self.set(

tests/test_store/test_logging.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ async def test_logging_store_counter(store: Store) -> None:
4747
assert wrapped.counter["set"] == 2
4848
assert wrapped.counter["list"] == 0
4949
assert wrapped.counter["list_dir"] == 0
50+
assert wrapped.counter["list_prefix"] == 0
5051
if store.supports_deletes:
5152
assert wrapped.counter["get"] == 0 # 1 if overwrite=False
52-
assert wrapped.counter["list_prefix"] == 1
53+
assert wrapped.counter["delete_dir"] == 1
5354
else:
5455
assert wrapped.counter["get"] == 1
55-
assert wrapped.counter["list_prefix"] == 0
56+
assert wrapped.counter["delete_dir"] == 0
5657

5758

5859
async def test_with_mode():

tests/test_store/test_zip.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from zarr.testing.store import StoreTests
1515

1616
if TYPE_CHECKING:
17-
from collections.abc import Coroutine
1817
from typing import Any
1918

2019

@@ -65,9 +64,6 @@ def test_store_supports_partial_writes(self, store: ZipStore) -> None:
6564
def test_store_supports_listing(self, store: ZipStore) -> None:
6665
assert store.supports_listing
6766

68-
def test_delete(self, store: ZipStore) -> Coroutine[Any, Any, None]:
69-
pass
70-
7167
def test_api_integration(self, store: ZipStore) -> None:
7268
root = zarr.open_group(store=store)
7369

0 commit comments

Comments
 (0)