8000 correct array.nbytes, and add tests (#2576) · rtobar/zarr-python@1cc3917 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1cc3917

Browse files
authored
correct array.nbytes, and add tests (zarr-developers#2576)
* correct array.nbytes, and add tests * use nbytes in array info construction * stronger docstrings
1 parent 5bf7bcf commit 1cc3917

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/zarr/core/array.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,9 +977,17 @@ def _iter_chunk_regions(
977977
@property
978978
def nbytes(self) -> int:
979979
"""
980-
The number of bytes that can be stored in this array.
980+
The total number of bytes that can be stored in the chunks of this array.
981+
982+
Notes
983+
-----
984+
This value is calculated by multiplying the number of elements in the array and the size
985+
of each element, the latter of which is determined by the dtype of the array.
986+
For this reason, ``nbytes`` will likely be inaccurate for arrays with variable-length
987+
dtypes. It is not possible to determine the size of an array with variable-length elements
988+
from the shape and dtype alone.
981989
"""
982-
return self.nchunks * self.dtype.itemsize
990+
return self.size * self.dtype.itemsize
983991

984992
async def _get_selection(
985993
self,
@@ -1429,7 +1437,7 @@ def _info(
14291437
_order=self.order,
14301438
_read_only=self.read_only,
14311439
_store_type=type(self.store_path.store).__name__,
1432-
_count_bytes=self.dtype.itemsize * self.size,
1440+
_count_bytes=self.nbytes,
14331441
_count_bytes_stored=count_bytes_stored,
14341442
_count_chunks_initialized=count_chunks_initialized,
14351443
**kwargs,
@@ -1740,7 +1748,15 @@ def _iter_chunk_coords(
17401748
@property
17411749
def nbytes(self) -> int:
17421750
"""
1743< 10000 /td>-
The number of bytes that can be stored in this array.
1751+
The total number of bytes that can be stored in the chunks of this array.
1752+
1753+
Notes
1754+
-----
1755+
This value is calculated by multiplying the number of elements in the array and the size
1756+
of each element, the latter of which is determined by the dtype of the array.
1757+
For this reason, ``nbytes`` will likely be inaccurate for arrays with variable-length
1758+
dtypes. It is not possible to determine the size of an array with variable-length elements
1759+
from the shape and dtype alone.
17441760
"""
17451761
return self._async_array.nbytes
17461762

tests/test_array.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,3 +776,21 @@ async def test_special_complex_fill_values_roundtrip(fill_value: Any, expected:
776776
assert content is not None
777777
actual = json.loads(content.to_bytes())
778778
assert actual["fill_value"] == expected
779+
780+
781+
@pytest.mark.parametrize("shape", [(1,), (2, 3), (4, 5, 6)])
782+
@pytest.mark.parametrize("dtype", ["uint8", "float32"])
783+
@pytest.mark.parametrize("array_type", ["async", "sync"])
784+
async def test_nbytes(
785+
shape: tuple[int, ...], dtype: str, array_type: Literal["async", "sync"]
786+
) -> None:
787+
"""
788+
Test that the ``nbytes`` attribute of an Array or AsyncArray correctly reports the capacity of
789+
the chunks of that array.
790+
"""
791+
store = MemoryStore()
792+
arr = Array.create(store=store, shape=shape, dtype=dtype, fill_value=0)
793+
if array_type == "async":
794+
assert arr._async_array.nbytes == np.prod(arr.shape) * arr.dtype.itemsize
795+
else:
796+
assert arr.nbytes == np.prod(arr.shape) * arr.dtype.itemsize

0 commit comments

Comments
 (0)
0