8000 Feature: group and array name properties (#1940) · AdamWill/zarr-python@72005d7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 72005d7

Browse files
authored
Feature: group and array name properties (zarr-developers#1940)
* feature: group and array path/name/basename properties * tests
1 parent 24e855c commit 72005d7

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

src/zarr/array.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,29 @@ def dtype(self) -> np.dtype[Any]:
378378
def attrs(self) -> dict[str, 10000 JSON]:
379379
return self.metadata.attributes
380380

381+
@property
382+
def path(self) -> str:
383+
"""Storage path."""
384+
return self.store_path.path
385+
386+
@property
387+
def name(self) -> str | None:
388+
"""Array name following h5py convention."""
389+
if self.path:
390+
# follow h5py convention: add leading slash
391+
name = self.path
392+
if name[0] != "/":
393+
name = "/" + name
394+
return name
395+
return None
396+
397+
@property
398+
def basename(self) -> str | None:
399+
"""Final component of name."""
400+
if self.name is not None:
401+
return self.name.split("/")[-1]
402+
return None
403+
381404
async def _get_selection(
382405
self,
383406
indexer: Indexer,
@@ -630,6 +653,21 @@ def dtype(self) -> np.dtype[Any]:
630653
def attrs(self) -> Attributes:
631654
return Attributes(self)
632655

656+
@property
657+
def path(self) -> str:
658+
"""Storage path."""
659+
return self._async_array.path
660+
661+
@property
662+
def name(self) -> str | None:
663+
"""Array name following h5py convention."""
664+
return self._async_array.name
665+
666+
@property
667+
def basename(self) -> str | None:
668+
"""Final component of name."""
669+
return self._async_array.basename
670+
633671
@property
634672
def metadata(self) -> ArrayMetadata:
635673
return self._async_array.metadata

src/zarr/group.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,27 @@ async def _save_metadata(self) -> None:
270270
awaitables = [set_or_delete(self.store_path / key, value) for key, value in to_save.items()]
271271
await asyncio.gather(*awaitables)
272272

273+
@property
274+
def path(self) -> str:
275+
"""Storage path."""
276+
return self.store_path.path
277+
278+
@property
279+
def name(self) -> str:
280+
"""Group name following h5py convention."""
281+
if self.path:
282+
# follow h5py convention: add leading slash
283+
name = self.path
284+
if name[0] != "/":
285+
name = "/" + name
286+
return name
287+
return "/"
288+
289+
@property
290+
def basename(self) -> str:
291+
"""Final component of name."""
292+
return self.name.split("/")[-1]
293+
273294
@property
274295
def attrs(self) -> dict[str, Any]:
275296
return self.metadata.attributes
@@ -462,13 +483,15 @@ def create(
462483
store: StoreLike,
463484
*,
464485
attributes: dict[str, Any] = {}, # noqa: B006, FIXME
486+
zarr_format: ZarrFormat = 3,
465487
exists_ok: bool = False,
466488
) -> Group:
467489
obj = sync(
468490
AsyncGroup.create(
469491
store,
470492
attributes=attributes,
471493
exists_ok=exists_ok,
494+
zarr_format=zarr_format,
472495
),
473496
)
474497

@@ -521,6 +544,21 @@ def store_path(self) -> StorePath:
521544
def metadata(self) -> GroupMetadata:
522545
return self._async_group.metadata
523546

547+
@property
548+
def path(self) -> str:
549+
"""Storage path."""
550+
return self._async_group.path
551+
552+
@property
553+
def name(self) -> str:
554+
"""Group name following h5py convention."""
555+
return self._async_group.name
556+
557+
@property
558+
def basename(self) -> str:
559+
"""Final component of name."""
560+
return self._async_group.basename
561+
524562
@property
525563
def attrs(self) -> Attributes:
526564
return Attributes(self)

tests/v3/test_array.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import pytest
2+
3+
from zarr.array import Array
4+
from zarr.common import ZarrFormat
5+
from zarr.group import Group
6+
from zarr.store import LocalStore, MemoryStore
7+
8+
9+
@pytest.mark.parametrize("store", ("local", "memory"), indirect=["store"])
10+
@pytest.mark.parametrize("zarr_format", (2, 3))
11+
def test_array_name_properties_no_group(
12+
store: LocalStore | MemoryStore, zarr_format: ZarrFormat
13+
) -> None:
14+
arr = Array.create(store=store, shape=(100,), chunks=(10,), zarr_format=zarr_format, dtype="i4")
15+
assert arr.path == ""
16+
assert arr.name is None
17+
assert arr.basename is None
18+
19+
20+
@pytest.mark.parametrize("store", ("local", "memory"), indirect=["store"])
21+
@pytest.mark.parametrize("zarr_format", (2, 3))
22+
def test_array_name_properties_with_group(
23+
store: LocalStore | MemoryStore, zarr_format: ZarrFormat
24+
) -> None:
25+
root = Group.create(store=store, zarr_format=zarr_format)
26+
foo = root.create_array("foo", shape=(100,), chunks=(10,), dtype="i4")
27+
assert foo.path == "foo"
28+
assert foo.name == "/foo"
29+
assert foo.basename == "foo"
30+
31+
bar = root.create_group("bar")
32+
spam = bar.create_array("spam", shape=(100,), chunks=(10,), dtype="i4")
33+
34+
assert spam.path == "bar/spam"
35+
assert spam.name == "/bar/spam"
36+
assert spam.basename == "spam"

tests/v3/test_group.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,3 +372,22 @@ def test_group_init(store: LocalStore | MemoryStore, zarr_format: ZarrFormat) ->
372372
agroup = sync(AsyncGroup.create(store=store, zarr_format=zarr_format))
373373
group = Group(agroup)
374374
assert group._async_group == agroup
375+
376+
377+
@pytest.mark.parametrize("store", ("local", "memory"), indirect=["store"])
378+
@pytest.mark.parametrize("zarr_format", (2, 3))
379+
def test_group_name_properties(store: LocalStore | MemoryStore, zarr_format: ZarrFormat) -> None:
380+
root = Group.create(store=store, zarr_format=zarr_format)
381+
assert root.path == ""
382+
assert root.name == "/"
383+
assert root.basename == ""
384+
385+
foo = root.create_group("foo")
386+
assert foo.path == "foo"
387+
assert foo.name == "/foo"
388+
assert foo.basename == "foo"
389+
390+
bar = root.create_group("foo/bar")
391+
assert bar.path == "foo/bar"
392+
assert bar.name == "/foo/bar"
393+
assert bar.basename == "bar"

0 commit comments

Comments
 (0)
0