diff --git a/src/zarr/codecs/crc32c_.py b/src/zarr/codecs/crc32c_.py index ebe2ac8f7a..7d41e11637 100644 --- a/src/zarr/codecs/crc32c_.py +++ b/src/zarr/codecs/crc32c_.py @@ -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 @@ -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( @@ -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"))) diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index 2c2a4622e3..977520b12e 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -1,5 +1,6 @@ from __future__ import annotations +import math import warnings from asyncio import gather from collections.abc import Iterable, Mapping, Sequence @@ -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, ...]: diff --git a/src/zarr/core/chunk_grids.py b/src/zarr/core/chunk_grids.py index 7459908e0a..2cb9762775 100644 --- a/src/zarr/core/chunk_grids.py +++ b/src/zarr/core/chunk_grids.py @@ -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) diff --git a/src/zarr/core/codec_pipeline.py b/src/zarr/core/codec_pipeline.py index 032703fc03..23ecb0e255 100644 --- a/src/zarr/core/codec_pipeline.py +++ b/src/zarr/core/codec_pipeline.py @@ -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 @@ -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] diff --git a/src/zarr/core/common.py b/src/zarr/core/common.py index 570e3dfdc3..20664e553e 100644 --- a/src/zarr/core/common.py +++ b/src/zarr/core/common.py @@ -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 @@ -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: diff --git a/src/zarr/core/indexing.py b/src/zarr/core/indexing.py index d205d49a11..f6eb495cd9 100644 --- a/src/zarr/core/indexing.py +++ b/src/zarr/core/indexing.py @@ -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, @@ -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)) diff --git a/src/zarr/core/sync.py b/src/zarr/core/sync.py index 260d4ad841..160950ba64 100644 --- a/src/zarr/core/sync.py +++ b/src/zarr/core/sync.py @@ -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: @@ -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 diff --git a/src/zarr/storage/_local.py b/src/zarr/storage/_local.py index 3d9882d3db..1627c1a6b5 100644 --- a/src/zarr/storage/_local.py +++ b/src/zarr/storage/_local.py @@ -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