Skip to content

Commit a7f8bbf

Browse files
committed
add docstrings
1 parent 955f06c commit a7f8bbf

File tree

1 file changed

+158
-11
lines changed

1 file changed

+158
-11
lines changed

src/zarr/core/group.py

Lines changed: 158 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,23 @@
5555

5656

5757
def parse_zarr_format(data: Any) -> ZarrFormat:
58+
"""Parse the zarr_format field from metadata."""
5859
if data in (2, 3):
5960
return cast(Literal[2, 3], data)
6061
msg = f"Invalid zarr_format. Expected one of 2 or 3. Got {data}."
6162
raise ValueError(msg)
6263

6364

6465
def parse_node_type(data: Any) -> NodeType:
66+
"""Parse the node_type field from metadata."""
6567
if data in ("array", "group"):
6668
return cast(Literal["array", "group"], data)
6769
raise MetadataValidationError("node_type", "array or group", data)
6870

6971

7072
# todo: convert None to empty dict
7173
def parse_attributes(data: Any) -> dict[str, Any]:
74+
"""Parse the attributes field from metadata."""
7275
if data is None:
7376
return {}
7477
elif isinstance(data, dict) and all(isinstance(k, str) for k in data):
@@ -88,9 +91,7 @@ def _parse_async_node(node: AsyncGroup) -> Group: ...
8891
def _parse_async_node(
8992
node: AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | AsyncGroup,
9093
) -> Array | Group:
91-
"""
92-
Wrap an AsyncArray in an Array, or an AsyncGroup in a Group.
93-
"""
94+
"""Wrap an AsyncArray in an Array, or an AsyncGroup in a Group."""
9495
if isinstance(node, AsyncArray):
9596
return Array(node)
9697
elif isinstance(node, AsyncGroup):
@@ -297,6 +298,10 @@ def flatten(
297298

298299
@dataclass(frozen=True)
299300
class GroupMetadata(Metadata):
301+
"""
302+
Metadata for a Group.
303+
"""
304+
300305
attributes: dict[str, Any] = field(default_factory=dict)
301306
zarr_format: ZarrFormat = 3
302307
consolidated_metadata: ConsolidatedMetadata | None = None
@@ -391,6 +396,10 @@ def to_dict(self) -> dict[str, Any]:
391396

392397
@dataclass(frozen=True)
393398
class AsyncGroup:
399+
"""
400+
Asynchronous Group object.
401+
"""
402+
394403
metadata: GroupMetadata
395404
store_path: StorePath
396405

@@ -620,6 +629,18 @@ async def getitem(
620629
self,
621630
key: str,
622631
) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | AsyncGroup:
632+
"""
633+
Get a subarray or subgroup from the group.
634+
635+
Parameters
636+
----------
637+
key : str
638+
Array or group name
639+
640+
Returns
641+
-------
642+
AsyncArray or AsyncGroup
643+
"""
623644
store_path = self.store_path / key
624645
logger.debug("key=%s, store_path=%s", key, store_path)
625646

@@ -725,6 +746,13 @@ def _getitem_consolidated(
725746
return AsyncArray(metadata=metadata, store_path=store_path)
726747

727748
async def delitem(self, key: str) -> None:
749+
"""Delete a group member.
750+
751+
Parameters
752+
----------
753+
key : str
754+
Array or group name
755+
"""
728756
store_path = self.store_path / key
729757
if self.metadata.zarr_format == 3:
730758
await (store_path / ZARR_JSON).delete()
@@ -834,6 +862,21 @@ async def create_group(
834862
exists_ok: bool = False,
835863
attributes: dict[str, Any] | None = None,
836864
) -> AsyncGroup:
865+
"""Create a sub-group.
866+
867+
Parameters
868+
----------
869+
name : str
870+
Group name.
871+
exists_ok : bool, optional
872+
If True, do not raise an error if the group already exists.
873+
attributes : dict, optional
874+
Group attributes.
875+
876+
Returns
877+
-------
878+
g : AsyncGroup
879+
"""
837880
attributes = attributes or {}
838881
return await type(self).from_store(
839882
self.store_path / name,
@@ -875,7 +918,17 @@ async def require_group(self, name: str, overwrite: bool = False) -> AsyncGroup:
875918
return grp
876919

877920
async def require_groups(self, *names: str) -> tuple[AsyncGroup, ...]:
878-
"""Convenience method to require multiple groups in a single call."""
921+
"""Convenience method to require multiple groups in a single call.
922+
923+
Parameters
924+
----------
925+
*names : str
926+
Group names.
927+
928+
Returns
929+
-------
930+
Tuple[AsyncGroup, ...]
931+
"""
879932
if not names:
880933
return ()
881934
return tuple(await asyncio.gather(*(self.require_group(name) for name in names)))
@@ -1083,6 +1136,17 @@ async def require_array(
10831136
return ds
10841137

10851138
async def update_attributes(self, new_attributes: dict[str, Any]) -> AsyncGroup:
1139+
"""Update group attributes.
1140+
1141+
Parameters
1142+
----------
1143+
new_attributes : dict
1144+
New attributes to set on the group.
1145+
1146+
Returns
1147+
-------
1148+
self : AsyncGroup
1149+
"""
10861150
# metadata.attributes is "frozen" so we simply clear and update the dict
10871151
self.metadata.attributes.clear()
10881152
self.metadata.attributes.update(new_attributes)
@@ -1241,10 +1305,22 @@ def _members_consolidated(
12411305
yield from obj._members_consolidated(max_depth, current_depth + 1, prefix=key)
12421306

12431307
async def keys(self) -> AsyncGenerator[str, None]:
1308+
"""Iterate over member names."""
12441309
async for key, _ in self.members():
12451310
yield key
12461311

12471312
async def contains(self, member: str) -> bool:
1313+
"""Check if a member exists in the group.
1314+
1315+
Parameters
1316+
----------
1317+
member : str
1318+
Member name.
1319+
1320+
Returns
1321+
-------
1322+
bool
1323+
"""
12481324
# TODO: this can be made more efficient.
12491325
try:
12501326
await self.getitem(member)
@@ -1254,15 +1330,18 @@ async def contains(self, member: str) -> bool:
12541330
return True
12551331

12561332
async def groups(self) -> AsyncGenerator[tuple[str, AsyncGroup], None]:
1333+
"""Iterate over subgroups."""
12571334
async for name, value in self.members():
12581335
if isinstance(value, AsyncGroup):
12591336
yield name, value
12601337

12611338
async def group_keys(self) -> AsyncGenerator[str, None]:
1339+
"""Iterate over group names."""
12621340
async for key, _ in self.groups():
12631341
yield key
12641342

12651343
async def group_values(self) -> AsyncGenerator[AsyncGroup, None]:
1344+
"""Iterate over group values."""
12661345
async for _, group in self.groups():
12671346
yield group
12681347

@@ -1271,21 +1350,25 @@ async def arrays(
12711350
) -> AsyncGenerator[
12721351
tuple[str, AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]], None
12731352
]:
1353+
"""Iterate over arrays."""
12741354
async for key, value in self.members():
12751355
if isinstance(value, AsyncArray):
12761356
yield key, value
12771357

12781358
async def array_keys(self) -> AsyncGenerator[str, None]:
1359+
"""Iterate over array names."""
12791360
async for key, _ in self.arrays():
12801361
yield key
12811362

12821363
async def array_values(
12831364
self,
12841365
) -> AsyncGenerator[AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata], None]:
1366+
"""Iterate over array values."""
12851367
async for _, array in self.arrays():
12861368
yield array
12871369

12881370
async def tree(self, expand: bool = False, level: int | None = None) -> Any:
1371+
"""Return a nested representation of the group hierarchy."""
12891372
raise NotImplementedError
12901373

12911374
async def empty(
@@ -1467,7 +1550,12 @@ async def full_like(
14671550
return await async_api.full_like(a=data, store=self.store_path, path=name, **kwargs)
14681551

14691552
async def move(self, source: str, dest: str) -> None:
1470-
"""Not implemented"""
1553+
"""Move a sub-group or sub-array from one path to another.
1554+
1555+
Notes
1556+
-----
1557+
Not implemented
1558+
"""
14711559
raise NotImplementedError
14721560

14731561

@@ -1609,7 +1697,22 @@ def get(self, path: str, default: DefaultT | None = None) -> Array | Group | Def
16091697
return default
16101698

16111699
def __delitem__(self, key: str) -> None:
1612-
"""Delete a group member."""
1700+
"""Delete a group member.
1701+
1702+
Parameters
1703+
----------
1704+
key : str
1705+
Group member name.
1706+
1707+
Examples
1708+
--------
1709+
>>> import zarr
1710+
>>> group = Group.from_store(zarr.storage.MemoryStore(mode="w"))
1711+
>>> group.create_array(name="subarray", shape=(10,), chunk_shape=(10,))
1712+
>>> del group["subarray"]
1713+
>>> "subarray" in group
1714+
False
1715+
"""
16131716
self._sync(self._async_group.delitem(key))
16141717

16151718
def __iter__(self) -> Iterator[str]:
@@ -1639,6 +1742,22 @@ def __setitem__(self, key: str, value: Any) -> None:
16391742
"""Fastpath for creating a new array.
16401743
16411744
New arrays will be created using default settings for the array type.
1745+
If you need to create an array with custom settings, use the `create_array` method.
1746+
1747+
Parameters
1748+
----------
1749+
key : str
1750+
Array name.
1751+
value : Any
1752+
Array data.
1753+
1754+
Examples
1755+
--------
1756+
>>> import zarr
1757+
>>> group = zarr.group()
1758+
>>> group["foo"] = zarr.zeros((10,))
1759+
>>> group["foo"]
1760+
<Array memory://132270269438272/foo shape=(10,) dtype=float64>
16421761
"""
16431762
self._sync(self._async_group.setitem(key, value))
16441763

@@ -1647,6 +1766,7 @@ def __repr__(self) -> str:
16471766

16481767
async def update_attributes_async(self, new_attributes: dict[str, Any]) -> Group:
16491768
"""Update the attributes of this group.
1769+
16501770
Example
16511771
-------
16521772
>>> import zarr
@@ -1697,6 +1817,7 @@ def attrs(self) -> Attributes:
16971817

16981818
@property
16991819
def info(self) -> None:
1820+
"""Group information."""
17001821
raise NotImplementedError
17011822

17021823
@property
@@ -1757,6 +1878,7 @@ def members(self, max_depth: int | None = 0) -> tuple[tuple[str, Array | Group],
17571878

17581879
def keys(self) -> Generator[str, None]:
17591880
"""Return an iterator over group member names.
1881+
17601882
Examples
17611883
--------
17621884
>>> import zarr
@@ -1795,6 +1917,7 @@ def __contains__(self, member: str) -> bool:
17951917

17961918
def groups(self) -> Generator[tuple[str, Group], None]:
17971919
"""Return the sub-groups of this group as a generator of (name, group) pairs.
1920+
17981921
Example
17991922
-------
18001923
>>> import zarr
@@ -1809,6 +1932,7 @@ def groups(self) -> Generator[tuple[str, Group], None]:
18091932

18101933
def group_keys(self) -> Generator[str, None]:
18111934
"""Return an iterator over group member names.
1935+
18121936
Examples
18131937
--------
18141938
>>> import zarr
@@ -1823,6 +1947,7 @@ def group_keys(self) -> Generator[str, None]:
18231947

18241948
def group_values(self) -> Generator[Group, None]:
18251949
"""Return an iterator over group members.
1950+
18261951
Examples
18271952
--------
18281953
>>> import zarr
@@ -1836,8 +1961,8 @@ def group_values(self) -> Generator[Group, None]:
18361961
yield group
18371962

18381963
def arrays(self) -> Generator[tuple[str, Array], None]:
1839-
"""
1840-
Return the sub-arrays of this group as a generator of (name, array) pairs
1964+
"""Return the sub-arrays of this group as a generator of (name, array) pairs
1965+
18411966
Examples
18421967
--------
18431968
>>> import zarr
@@ -1852,6 +1977,7 @@ def arrays(self) -> Generator[tuple[str, Array], None]:
18521977

18531978
def array_keys(self) -> Generator[str, None]:
18541979
"""Return an iterator over group member names.
1980+
18551981
Examples
18561982
--------
18571983
>>> import zarr
@@ -1867,6 +1993,7 @@ def array_keys(self) -> Generator[str, None]:
18671993

18681994
def array_values(self) -> Generator[Array, None]:
18691995
"""Return an iterator over group members.
1996+
18701997
Examples
18711998
--------
18721999
>>> import zarr
@@ -1880,7 +2007,12 @@ def array_values(self) -> Generator[Array, None]:
18802007
yield array
18812008

18822009
def tree(self, expand: bool = False, level: int | None = None) -> Any:
1883-
"""Not implemented"""
2010+
"""Return a nested representation of the group hierarchy.
2011+
2012+
Notes
2013+
-----
2014+
Not implemented
2015+
"""
18842016
return self._sync(self._async_group.tree(expand=expand, level=level))
18852017

18862018
def create_group(self, name: str, **kwargs: Any) -> Group:
@@ -1920,7 +2052,17 @@ def require_group(self, name: str, **kwargs: Any) -> Group:
19202052
return Group(self._sync(self._async_group.require_group(name, **kwargs)))
19212053

19222054
def require_groups(self, *names: str) -> tuple[Group, ...]:
1923-
"""Convenience method to require multiple groups in a single call."""
2055+
"""Convenience method to require multiple groups in a single call.
2056+
2057+
Parameters
2058+
----------
2059+
*names : str
2060+
Group names.
2061+
2062+
Returns
2063+
-------
2064+
groups : tuple of Groups
2065+
"""
19242066
return tuple(map(Group, self._sync(self._async_group.require_groups(*names))))
19252067

19262068
def create(self, *args: Any, **kwargs: Any) -> Array:
@@ -2259,7 +2401,12 @@ def full_like(self, *, name: str, data: async_api.ArrayLike, **kwargs: Any) -> A
22592401
return Array(self._sync(self._async_group.full_like(name=name, data=data, **kwargs)))
22602402

22612403
def move(self, source: str, dest: str) -> None:
2262-
"""Not implemented"""
2404+
"""Move a sub-group or sub-array from one path to another.
2405+
2406+
Notes
2407+
-----
2408+
Not implemented
2409+
"""
22632410
return self._sync(self._async_group.move(source, dest))
22642411

22652412
@deprecated("Use Group.create_array instead.")

0 commit comments

Comments
 (0)