From 1b5c2ec076fb217822a95c37722e27c6f81c9127 Mon Sep 17 00:00:00 2001 From: dhruvak001 Date: Thu, 15 May 2025 00:13:16 +0530 Subject: [PATCH 1/6] Fix AsyncGroup.create_dataset() dtype handling and optimize tests --- changes/3050.bugfix.rst | 1 + src/zarr/core/group.py | 29 +++++++++++++++++++++-------- tests/test_properties.py | 13 ++++++++----- 3 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 changes/3050.bugfix.rst diff --git a/changes/3050.bugfix.rst b/changes/3050.bugfix.rst new file mode 100644 index 0000000000..c0b6678e78 --- /dev/null +++ b/changes/3050.bugfix.rst @@ -0,0 +1 @@ +- Fixed potential error in `AsyncGroup.create_dataset()` where `dtype` argument could be missing when calling `create_array()` diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index 5c470e29ca..1c2a36c30f 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -1155,8 +1155,11 @@ async def create_dataset( # create_dataset in zarr 2.x requires shape but not dtype if data is # provided. Allow this configuration by inferring dtype from data if # necessary and passing it to create_array - if "dtype" not in kwargs and data is not None: - kwargs["dtype"] = data.dtype + if "dtype" not in kwargs: + if data is not None: + kwargs["dtype"] = data.dtype + else: + raise ValueError("dtype must be provided if data is None") array = await self.create_array(name, shape=shape, **kwargs) if data is not None: await array.setitem(slice(None), data) @@ -2544,12 +2547,17 @@ def require_dataset(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Arra ---------- name : str Array name. - **kwargs : - See :func:`zarr.Group.create_dataset`. + shape : int or tuple of ints + Array shape. + dtype : str or dtype, optional + NumPy dtype. + exact : bool, optional + If True, require `dtype` to match exactly. If false, require + `dtype` can be cast from array dtype. Returns ------- - a : Array + a : AsyncArray """ return Array(self._sync(self._async_group.require_array(name, shape=shape, **kwargs))) @@ -2562,12 +2570,17 @@ def require_array(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Array: ---------- name : str Array name. - **kwargs : - See :func:`zarr.Group.create_array`. + shape : int or tuple of ints + Array shape. + dtype : str or dtype, optional + NumPy dtype. + exact : bool, optional + If True, require `dtype` to match exactly. If false, require + `dtype` can be cast from array dtype. Returns ------- - a : Array + a : AsyncArray """ return Array(self._sync(self._async_group.require_array(name, shape=shape, **kwargs))) diff --git a/tests/test_properties.py b/tests/test_properties.py index d48dfe2fef..c3355d136b 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -13,7 +13,7 @@ import hypothesis.extra.numpy as npst import hypothesis.strategies as st -from hypothesis import assume, given, settings +from hypothesis import assume, given, settings, HealthCheck from zarr.abc.store import Store from zarr.core.common import ZARR_JSON, ZARRAY_JSON, ZATTRS_JSON @@ -75,7 +75,7 @@ def deep_equal(a: Any, b: Any) -> bool: return a == b - +@settings(deadline=None) # Increased from default 200ms to None @given(data=st.data(), zarr_format=zarr_formats) def test_array_roundtrip(data: st.DataObject, zarr_format: int) -> None: nparray = data.draw(numpy_arrays(zarr_formats=st.just(zarr_format))) @@ -117,10 +117,11 @@ def test_basic_indexing(data: st.DataObject) -> None: assert_array_equal(nparray, zarray[:]) +@settings(deadline=None, suppress_health_check=[HealthCheck.too_slow]) @given(data=st.data()) def test_oindex(data: st.DataObject) -> None: # integer_array_indices can't handle 0-size dimensions. - zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=4, min_side=1))) + zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=3, min_side=1, max_side=8))) nparray = zarray[:] zindexer, npindexer = data.draw(orthogonal_indices(shape=nparray.shape)) @@ -138,15 +139,17 @@ def test_oindex(data: st.DataObject) -> None: assert_array_equal(nparray, zarray[:]) +@settings(deadline=None, suppress_health_check=[HealthCheck.too_slow]) @given(data=st.data()) def test_vindex(data: st.DataObject) -> None: # integer_array_indices can't handle 0-size dimensions. - zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=4, min_side=1))) + zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=3, min_side=1, max_side=8))) nparray = zarray[:] indexer = data.draw( npst.integer_array_indices( - shape=nparray.shape, result_shape=npst.array_shapes(min_side=1, max_dims=None) + shape=nparray.shape, + result_shape=npst.array_shapes(min_side=1, max_dims=2, max_side=8) ) ) actual = zarray.vindex[indexer] From 334e55cd240f3f111d74475d5b83201f4f128886 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 08:11:33 +0000 Subject: [PATCH 2/6] style: pre-commit fixes --- tests/test_properties.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_properties.py b/tests/test_properties.py index c3355d136b..eef0d510b4 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -13,7 +13,7 @@ import hypothesis.extra.numpy as npst import hypothesis.strategies as st -from hypothesis import assume, given, settings, HealthCheck +from hypothesis import HealthCheck, assume, given, settings from zarr.abc.store import Store from zarr.core.common import ZARR_JSON, ZARRAY_JSON, ZATTRS_JSON @@ -75,6 +75,7 @@ def deep_equal(a: Any, b: Any) -> bool: return a == b + @settings(deadline=None) # Increased from default 200ms to None @given(data=st.data(), zarr_format=zarr_formats) def test_array_roundtrip(data: st.DataObject, zarr_format: int) -> None: @@ -148,8 +149,7 @@ def test_vindex(data: st.DataObject) -> None: indexer = data.draw( npst.integer_array_indices( - shape=nparray.shape, - result_shape=npst.array_shapes(min_side=1, max_dims=2, max_side=8) + shape=nparray.shape, result_shape=npst.array_shapes(min_side=1, max_dims=2, max_side=8) ) ) actual = zarray.vindex[indexer] From 92bcbf98f948681f16f407ec45ccc6654a651d5b Mon Sep 17 00:00:00 2001 From: dhruvak001 Date: Mon, 19 May 2025 21:25:51 +0530 Subject: [PATCH 3/6] revert hypothesis tests --- tests/test_properties.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/test_properties.py b/tests/test_properties.py index eef0d510b4..d48dfe2fef 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -13,7 +13,7 @@ import hypothesis.extra.numpy as npst import hypothesis.strategies as st -from hypothesis import HealthCheck, assume, given, settings +from hypothesis import assume, given, settings from zarr.abc.store import Store from zarr.core.common import ZARR_JSON, ZARRAY_JSON, ZATTRS_JSON @@ -76,7 +76,6 @@ def deep_equal(a: Any, b: Any) -> bool: return a == b -@settings(deadline=None) # Increased from default 200ms to None @given(data=st.data(), zarr_format=zarr_formats) def test_array_roundtrip(data: st.DataObject, zarr_format: int) -> None: nparray = data.draw(numpy_arrays(zarr_formats=st.just(zarr_format))) @@ -118,11 +117,10 @@ def test_basic_indexing(data: st.DataObject) -> None: assert_array_equal(nparray, zarray[:]) -@settings(deadline=None, suppress_health_check=[HealthCheck.too_slow]) @given(data=st.data()) def test_oindex(data: st.DataObject) -> None: # integer_array_indices can't handle 0-size dimensions. - zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=3, min_side=1, max_side=8))) + zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=4, min_side=1))) nparray = zarray[:] zindexer, npindexer = data.draw(orthogonal_indices(shape=nparray.shape)) @@ -140,16 +138,15 @@ def test_oindex(data: st.DataObject) -> None: assert_array_equal(nparray, zarray[:]) -@settings(deadline=None, suppress_health_check=[HealthCheck.too_slow]) @given(data=st.data()) def test_vindex(data: st.DataObject) -> None: # integer_array_indices can't handle 0-size dimensions. - zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=3, min_side=1, max_side=8))) + zarray = data.draw(simple_arrays(shapes=npst.array_shapes(max_dims=4, min_side=1))) nparray = zarray[:] indexer = data.draw( npst.integer_array_indices( - shape=nparray.shape, result_shape=npst.array_shapes(min_side=1, max_dims=2, max_side=8) + shape=nparray.shape, result_shape=npst.array_shapes(min_side=1, max_dims=None) ) ) actual = zarray.vindex[indexer] From 63e95c84beed835fb48a768ce27d24b8b830894f Mon Sep 17 00:00:00 2001 From: dhruvak001 Date: Mon, 19 May 2025 23:46:45 +0530 Subject: [PATCH 4/6] numpydoc error --- src/zarr/core/group.py | 70 +++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index 1c2a36c30f..be9c47ecae 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -1165,12 +1165,12 @@ async def create_dataset( await array.setitem(slice(None), data) return array - @deprecated("Use AsyncGroup.require_array instead.") - async def require_dataset( + @deprecated("Use Group.require_array instead.") + def require_dataset( self, name: str, *, - shape: ChunkCoords, + shape: ShapeLike, dtype: npt.DTypeLike = None, exact: bool = False, **kwargs: Any, @@ -1178,12 +1178,12 @@ async def require_dataset( """Obtain an array, creating if it doesn't exist. .. deprecated:: 3.0.0 - The h5py compatibility methods will be removed in 3.1.0. Use `AsyncGroup.require_dataset` instead. + The h5py compatibility methods will be removed in 3.1.0. Use `Group.require_array` instead. Arrays are known as "datasets" in HDF5 terminology. For compatibility with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.create_dataset` method. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_dataset`. + Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. Parameters ---------- @@ -1191,17 +1191,14 @@ async def require_dataset( Array name. shape : int or tuple of ints Array shape. - dtype : str or dtype, optional - NumPy dtype. - exact : bool, optional - If True, require `dtype` to match exactly. If false, require - `dtype` can be cast from array dtype. + **kwargs + Additional keyword arguments passed to :func:`zarr.AsyncGroup.create_array`. Returns ------- a : AsyncArray """ - return await self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) + return self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) async def require_array( self, @@ -1214,7 +1211,7 @@ async def require_array( ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: """Obtain an array, creating if it doesn't exist. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_dataset`. + Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. Parameters ---------- @@ -1223,9 +1220,9 @@ async def require_array( shape : int or tuple of ints Array shape. dtype : str or dtype, optional - NumPy dtype. + NumPy dtype. If None, the dtype will be inferred from the existing array. exact : bool, optional - If True, require `dtype` to match exactly. If false, require + If True, require `dtype` to match exactly. If False, require `dtype` can be cast from array dtype. Returns @@ -2514,34 +2511,41 @@ def create_dataset(self, name: str, **kwargs: Any) -> Array: .. deprecated:: 3.0.0 The h5py compatibility methods will be removed in 3.1.0. Use `Group.create_array` instead. - Arrays are known as "datasets" in HDF5 terminology. For compatibility - with h5py, Zarr groups also implement the :func:`zarr.Group.require_dataset` method. + with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.require_dataset` method. Parameters ---------- name : str Array name. **kwargs : dict - Additional arguments passed to :func:`zarr.Group.create_array` + Additional arguments passed to :func:`zarr.AsyncGroup.create_array`. Returns ------- - a : Array + a : AsyncArray """ return Array(self._sync(self._async_group.create_dataset(name, **kwargs))) @deprecated("Use Group.require_array instead.") - def require_dataset(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Array: + def require_dataset( + self, + name: str, + *, + shape: ShapeLike, + dtype: npt.DTypeLike = None, + exact: bool = False, + **kwargs: Any, + ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: """Obtain an array, creating if it doesn't exist. .. deprecated:: 3.0.0 The h5py compatibility methods will be removed in 3.1.0. Use `Group.require_array` instead. Arrays are known as "datasets" in HDF5 terminology. For compatibility - with h5py, Zarr groups also implement the :func:`zarr.Group.create_dataset` method. + with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.create_dataset` method. - Other `kwargs` are as per :func:`zarr.Group.create_dataset`. + Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. Parameters ---------- @@ -2559,12 +2563,20 @@ def require_dataset(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Arra ------- a : AsyncArray """ - return Array(self._sync(self._async_group.require_array(name, shape=shape, **kwargs))) + return self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) - def require_array(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Array: + def require_array( + self, + name: str, + *, + shape: ShapeLike, + dtype: npt.DTypeLike = None, + exact: bool = False, + **kwargs: Any, + ) -> Array: """Obtain an array, creating if it doesn't exist. - Other `kwargs` are as per :func:`zarr.Group.create_array`. + Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. Parameters ---------- @@ -2573,16 +2585,16 @@ def require_array(self, name: str, *, shape: ShapeLike, **kwargs: Any) -> Array: shape : int or tuple of ints Array shape. dtype : str or dtype, optional - NumPy dtype. + NumPy dtype. If None, the dtype will be inferred from the existing array. exact : bool, optional - If True, require `dtype` to match exactly. If false, require + If True, require `dtype` to match exactly. If False, require `dtype` can be cast from array dtype. Returns ------- - a : AsyncArray + a : Array """ - return Array(self._sync(self._async_group.require_array(name, shape=shape, **kwargs))) + return Array(self._sync(self._async_group.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs))) @_deprecate_positional_args def empty(self, *, name: str, shape: ChunkCoords, **kwargs: Any) -> Array: @@ -2931,7 +2943,7 @@ async def create_hierarchy( This function will parse its input to ensure that the hierarchy is complete. Any implicit groups will be inserted as needed. For example, an input like ```{'a/b': GroupMetadata}``` will be parsed to - ```{'': GroupMetadata, 'a': GroupMetadata, 'b': Groupmetadata}``` + ```{'': GroupMetadata, 'a': GroupMetadata, 'b': Groupmetadata}```. After input parsing, this function then creates all the nodes in the hierarchy concurrently. From 798132f8d3ad60042ec042a4cf63c7988fa8fa18 Mon Sep 17 00:00:00 2001 From: dhruvak001 Date: Tue, 20 May 2025 00:07:18 +0530 Subject: [PATCH 5/6] precommit error --- src/zarr/core/group.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index be9c47ecae..daa5de84d9 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -1174,16 +1174,16 @@ def require_dataset( dtype: npt.DTypeLike = None, exact: bool = False, **kwargs: Any, - ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: + ) -> Array: """Obtain an array, creating if it doesn't exist. .. deprecated:: 3.0.0 The h5py compatibility methods will be removed in 3.1.0. Use `Group.require_array` instead. Arrays are known as "datasets" in HDF5 terminology. For compatibility - with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.create_dataset` method. + with h5py, Zarr groups also implement the :func:`zarr.Group.create_dataset` method. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. + Other `kwargs` are as per :func:`zarr.Group.create_array`. Parameters ---------- @@ -1191,12 +1191,15 @@ def require_dataset( Array name. shape : int or tuple of ints Array shape. - **kwargs - Additional keyword arguments passed to :func:`zarr.AsyncGroup.create_array`. + dtype : str or dtype, optional + NumPy dtype. If None, the dtype will be inferred from the existing array. + exact : bool, optional + If True, require `dtype` to match exactly. If False, require + `dtype` can be cast from array dtype. Returns ------- - a : AsyncArray + a : Array """ return self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) @@ -2554,9 +2557,9 @@ def require_dataset( shape : int or tuple of ints Array shape. dtype : str or dtype, optional - NumPy dtype. + NumPy dtype. If None, the dtype will be inferred from the existing array. exact : bool, optional - If True, require `dtype` to match exactly. If false, require + If True, require `dtype` to match exactly. If False, require `dtype` can be cast from array dtype. Returns @@ -2592,9 +2595,15 @@ def require_array( Returns ------- - a : Array + a : AsyncArray """ - return Array(self._sync(self._async_group.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs))) + return Array( + self._sync( + self._async_group.require_array( + name, shape=shape, dtype=dtype, exact=exact, **kwargs + ) + ) + ) @_deprecate_positional_args def empty(self, *, name: str, shape: ChunkCoords, **kwargs: Any) -> Array: From 5a383cf70639ededfd8b2086e911aeb79dd3bb48 Mon Sep 17 00:00:00 2001 From: dhruvak001 Date: Tue, 20 May 2025 18:08:16 +0530 Subject: [PATCH 6/6] final precommit --- src/zarr/core/group.py | 118 ++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 37 deletions(-) diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index daa5de84d9..974044b6b6 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -47,7 +47,6 @@ NodeType, ShapeLike, ZarrFormat, - parse_shapelike, ) from zarr.core.config import config from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata @@ -441,9 +440,8 @@ class AsyncGroup: metadata: GroupMetadata store_path: StorePath - - # TODO: make this correct and work - # TODO: ensure that this can be bound properly to subclass of AsyncGroup + _sync: Any = field(default=None, init=False) + _async_group: Any = field(default=None, init=False) @classmethod async def from_store( @@ -991,6 +989,53 @@ async def require_groups(self, *names: str) -> tuple[AsyncGroup, ...]: return () return tuple(await asyncio.gather(*(self.require_group(name) for name in names))) + async def _require_array_async( + self, + name: str, + *, + shape: ShapeLike, + dtype: npt.DTypeLike = None, + exact: bool = False, + **kwargs: Any, + ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: + """Obtain an array, creating if it doesn't exist. + + Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. + + Parameters + ---------- + name : str + Array name. + shape : int or tuple of ints + Array shape. + dtype : str or dtype, optional + NumPy dtype. If None, the dtype will be inferred from the existing array. + exact : bool, optional + If True, require `dtype` to match exactly. If False, require + `dtype` can be cast from array dtype. + + Returns + ------- + a : AsyncArray + """ + try: + item = await self.getitem(name) + except KeyError: + # If it doesn't exist, create it + return await self.create_array(name, shape=shape, dtype=dtype, **kwargs) + else: + # Existing item must be an AsyncArray with matching dtype/shape + if not isinstance(item, AsyncArray): + raise TypeError(f"Incompatible object ({item.__class__.__name__}) already exists") + assert isinstance(item, AsyncArray) # mypy + if exact and dtype is not None and item.dtype != np.dtype(dtype): + raise TypeError("Incompatible dtype") + if not exact and dtype is not None and not np.can_cast(item.dtype, dtype): + raise TypeError("Incompatible dtype") + if item.shape != shape: + raise TypeError("Incompatible shape") + return item + async def create_array( self, name: str, @@ -1181,7 +1226,7 @@ def require_dataset( The h5py compatibility methods will be removed in 3.1.0. Use `Group.require_array` instead. Arrays are known as "datasets" in HDF5 terminology. For compatibility - with h5py, Zarr groups also implement the :func:`zarr.Group.create_dataset` method. + with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.create_dataset` method. Other `kwargs` are as per :func:`zarr.Group.create_array`. @@ -1201,9 +1246,15 @@ def require_dataset( ------- a : Array """ - return self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) + return Array( + self._sync( + self._async_group._require_array_async( + name, shape=shape, dtype=dtype, exact=exact, **kwargs + ) + ) + ) - async def require_array( + def require_array( self, name: str, *, @@ -1211,10 +1262,10 @@ async def require_array( dtype: npt.DTypeLike = None, exact: bool = False, **kwargs: Any, - ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: + ) -> Array: """Obtain an array, creating if it doesn't exist. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. + Other `kwargs` are as per :func:`zarr.Group.create_array`. Parameters ---------- @@ -1230,28 +1281,15 @@ async def require_array( Returns ------- - a : AsyncArray + a : Array """ - try: - ds = await self.getitem(name) - if not isinstance(ds, AsyncArray): - raise TypeError(f"Incompatible object ({ds.__class__.__name__}) already exists") - - shape = parse_shapelike(shape) - if shape != ds.shape: - raise TypeError(f"Incompatible shape ({ds.shape} vs {shape})") - - dtype = np.dtype(dtype) - if exact: - if ds.dtype != dtype: - raise TypeError(f"Incompatible dtype ({ds.dtype} vs {dtype})") - else: - if not np.can_cast(ds.dtype, dtype): - raise TypeError(f"Incompatible dtype ({ds.dtype} vs {dtype})") - except KeyError: - ds = await self.create_array(name, shape=shape, dtype=dtype, **kwargs) - - return ds + return Array( + self._sync( + self._async_group._require_array_async( + name, shape=shape, dtype=dtype, exact=exact, **kwargs + ) + ) + ) async def update_attributes(self, new_attributes: dict[str, Any]) -> AsyncGroup: """Update group attributes. @@ -2539,7 +2577,7 @@ def require_dataset( dtype: npt.DTypeLike = None, exact: bool = False, **kwargs: Any, - ) -> AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata]: + ) -> Array: """Obtain an array, creating if it doesn't exist. .. deprecated:: 3.0.0 @@ -2548,7 +2586,7 @@ def require_dataset( Arrays are known as "datasets" in HDF5 terminology. For compatibility with h5py, Zarr groups also implement the :func:`zarr.AsyncGroup.create_dataset` method. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. + Other `kwargs` are as per :func:`zarr.Group.create_array`. Parameters ---------- @@ -2564,9 +2602,15 @@ def require_dataset( Returns ------- - a : AsyncArray + a : Array """ - return self.require_array(name, shape=shape, dtype=dtype, exact=exact, **kwargs) + return Array( + self._sync( + self._async_group._require_array_async( + name, shape=shape, dtype=dtype, exact=exact, **kwargs + ) + ) + ) def require_array( self, @@ -2579,7 +2623,7 @@ def require_array( ) -> Array: """Obtain an array, creating if it doesn't exist. - Other `kwargs` are as per :func:`zarr.AsyncGroup.create_array`. + Other `kwargs` are as per :func:`zarr.Group.create_array`. Parameters ---------- @@ -2595,11 +2639,11 @@ def require_array( Returns ------- - a : AsyncArray + a : Array """ return Array( self._sync( - self._async_group.require_array( + self._async_group._require_array_async( name, shape=shape, dtype=dtype, exact=exact, **kwargs ) )