Skip to content
10 changes: 3 additions & 7 deletions src/zarr/codecs/crc32c_.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from __future__ import annotations

from collections.abc import Buffer as ABCBuffer
from dataclasses import dataclass
from typing import TYPE_CHECKING, cast

import google_crc32c
import numpy as np
import typing_extensions

from zarr.abc.codec import BytesBytesCodec
from zarr.core.common import JSON, parse_named_configuration
Expand Down Expand Up @@ -41,9 +41,7 @@ def _decode_sync(
inner_bytes = data[:-4]

# Need to do a manual cast until https://github.com/numpy/numpy/issues/26783 is resolved
computed_checksum = np.uint32(
google_crc32c.value(cast("typing_extensions.Buffer", inner_bytes))
).tobytes()
computed_checksum = np.uint32(google_crc32c.value(cast(ABCBuffer, inner_bytes))).tobytes()
stored_checksum = bytes(crc32_bytes)
if computed_checksum != stored_checksum:
raise ValueError(
Expand All @@ -65,9 +63,7 @@ def _encode_sync(
) -> Buffer | None:
data = chunk_bytes.as_numpy_array()
# Calculate the checksum and "cast" it to a numpy array
checksum = np.array(
[google_crc32c.value(cast("typing_extensions.Buffer", data))], dtype=np.uint32
)
checksum = np.array([google_crc32c.value(cast(ABCBuffer, data))], dtype=np.uint32)
# Append the checksum (as bytes) to the data
return chunk_spec.prototype.buffer.from_array_like(np.append(data, checksum.view("B")))

Expand Down
3 changes: 2 additions & 1 deletion src/zarr/core/array.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import math
import warnings
from asyncio import gather
from collections.abc import Iterable, Mapping, Sequence
Expand Down Expand Up @@ -905,7 +906,7 @@ def size(self) -> int:
int
Total number of elements in the array
"""
return np.prod(self.metadata.shape).item()
return math.prod(self.metadata.shape)

@property
def filters(self) -> tuple[Numcodec, ...] | tuple[ArrayArrayCodec, ...]:
Expand Down
2 changes: 1 addition & 1 deletion src/zarr/core/chunk_grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ def _guess_num_chunks_per_axis_shard(
-------
The number of chunks per axis.
"""
bytes_per_chunk = np.prod(chunk_shape) * item_size
bytes_per_chunk = math.prod(chunk_shape) * item_size
if max_bytes < bytes_per_chunk:
return 1
num_axes = len(chunk_shape)
Expand Down
10 changes: 1 addition & 9 deletions src/zarr/core/codec_pipeline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from dataclasses import dataclass, field
from itertools import islice, pairwise
from itertools import batched, pairwise
from typing import TYPE_CHECKING, Any
from warnings import warn

Expand Down Expand Up @@ -42,14 +42,6 @@ def _unzip2[T, U](iterable: Iterable[tuple[T, U]]) -> tuple[list[T], list[U]]:
return (out0, out1)


def batched[T](iterable: Iterable[T], n: int) -> Iterable[tuple[T, ...]]:
if n < 1:
raise ValueError("n must be at least one")
it = iter(iterable)
while batch := tuple(islice(it, n)):
yield batch


def resolve_batched(codec: Codec, chunk_specs: Iterable[ArraySpec]) -> Iterable[ArraySpec]:
return [codec.resolve_metadata(chunk_spec) for chunk_spec in chunk_specs]

Expand Down
4 changes: 1 addition & 3 deletions src/zarr/core/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from __future__ import annotations

import asyncio
import functools
import math
import operator
import warnings
from collections.abc import Iterable, Mapping, Sequence
from enum import Enum
Expand Down Expand Up @@ -83,7 +81,7 @@ class NamedRequiredConfig[TName: str, TConfig: Mapping[str, object]](TypedDict):


def product(tup: tuple[int, ...]) -> int:
return functools.reduce(operator.mul, tup, 1)
return math.prod(tup)


def ceildiv(a: float, b: float) -> int:
Expand Down
6 changes: 3 additions & 3 deletions src/zarr/core/indexing.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from __future__ import annotations

import itertools
import math
import numbers
import operator
from collections.abc import Iterator, Sequence
from dataclasses import dataclass
from enum import Enum
from functools import lru_cache, reduce
from functools import lru_cache
from types import EllipsisType
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -1187,7 +1187,7 @@ def __init__(
cdata_shape = (1,)
else:
cdata_shape = tuple(g.nchunks for g in dim_grids)
nchunks = reduce(operator.mul, cdata_shape, 1)
nchunks = math.prod(cdata_shape)

# some initial normalization
selection_normalized = cast("CoordinateSelectionNormalized", ensure_tuple(selection))
Expand Down
4 changes: 0 additions & 4 deletions src/zarr/core/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
from concurrent.futures import ThreadPoolExecutor, wait
from typing import TYPE_CHECKING

from typing_extensions import ParamSpec

from zarr.core.config import config

if TYPE_CHECKING:
Expand All @@ -19,8 +17,6 @@
logger = logging.getLogger(__name__)


P = ParamSpec("P")

# From https://github.com/fsspec/filesystem_spec/blob/master/fsspec/asyn.py

iothread: list[threading.Thread | None] = [None] # dedicated IO thread
Expand Down
4 changes: 2 additions & 2 deletions src/zarr/storage/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,10 @@ async def move(self, dest_root: Path | str) -> None:
if isinstance(dest_root, str):
dest_root = Path(dest_root)
os.makedirs(dest_root.parent, exist_ok=True)
if os.path.exists(dest_root):
if dest_root.exists():
raise FileExistsError(f"Destination root {dest_root} already exists.")
shutil.move(self.root, dest_root)
self.root = dest_root

async def getsize(self, key: str) -> int:
return os.path.getsize(self.root / key)
return (self.root / key).stat().st_size
Loading