Skip to content

Commit

Permalink
Merge branch 'main' into fix-hypothesis
Browse files Browse the repository at this point in the history
  • Loading branch information
d-v-b authored Nov 11, 2024
2 parents ec058cd + e5135f9 commit 7a92479
Show file tree
Hide file tree
Showing 39 changed files with 1,125 additions and 194 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
with:
name: releases
path: dist
- uses: pypa/gh-action-pypi-publish@v1.11.0
- uses: pypa/gh-action-pypi-publish@v1.12.2
with:
user: __token__
password: ${{ secrets.pypi_password }}
Expand Down
17 changes: 8 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@ jobs:
numpy-version: '2.1'
dependency-set: 'optional'
os: 'macos-latest'
# https://github.com/zarr-developers/zarr-python/issues/2438
# - python-version: '3.11'
# numpy-version: '1.25'
# dependency-set: 'optional'
# os: 'windows-latest'
# - python-version: '3.13'
# numpy-version: '2.1'
# dependency-set: 'optional'
# os: 'windows-latest'
- python-version: '3.11'
numpy-version: '1.25'
dependency-set: 'optional'
os: 'windows-latest'
- python-version: '3.13'
numpy-version: '2.1'
dependency-set: 'optional'
os: 'windows-latest'
runs-on: ${{ matrix.os }}

steps:
Expand Down
11 changes: 9 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -269,19 +269,25 @@ extend-exclude = [
extend-select = [
"ANN", # flake8-annotations
"B", # flake8-bugbear
"EXE", # flake8-executable
"C4", # flake8-comprehensions
"FA", # flake8-future-annotations
"FLY", # flynt
"FURB", # refurb
"G", # flake8-logging-format
"I", # isort
"ISC", # flake8-implicit-str-concat
"LOG", # flake8-logging
"PERF", # Perflint
"PIE", # flake8-pie
"PGH", # pygrep-hooks
"PT", # flake8-pytest-style
"PYI", # flake8-pyi
"RSE", # flake8-raise
"RET", # flake8-return
"RSE", # flake8-raise
"RUF",
"SIM", # flake8-simplify
"SLOT", # flake8-slots
"TCH", # flake8-type-checking
"TRY", # tryceratops
"UP", # pyupgrade
Expand All @@ -298,6 +304,7 @@ ignore = [
"RET505",
"RET506",
"RUF005",
"SIM108",
"TRY003",
"UP027", # deprecated
"UP038", # https://github.com/astral-sh/ruff/issues/7871
Expand All @@ -319,7 +326,7 @@ ignore = [
]

[tool.ruff.lint.extend-per-file-ignores]
"tests/**" = ["ANN001", "ANN201"]
"tests/**" = ["ANN001", "ANN201", "RUF029", "SIM117", "SIM300"]

[tool.mypy]
python_version = "3.11"
Expand Down
1 change: 0 additions & 1 deletion src/zarr/abc/codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def validate(self, *, shape: ChunkCoords, dtype: np.dtype[Any], chunk_grid: Chun
chunk_grid : ChunkGrid
The array chunk grid
"""
...

async def _decode_single(self, chunk_data: CodecOutput, chunk_spec: ArraySpec) -> CodecInput:
raise NotImplementedError
Expand Down
1 change: 0 additions & 1 deletion src/zarr/abc/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,5 @@ def from_dict(cls, data: dict[str, JSON]) -> Self:
"""
Create an instance of the model from a dictionary
"""
...

return cls(**data)
27 changes: 16 additions & 11 deletions src/zarr/abc/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import TYPE_CHECKING, NamedTuple, Protocol, runtime_checkable

if TYPE_CHECKING:
from collections.abc import AsyncGenerator, Iterable
from collections.abc import AsyncGenerator, AsyncIterator, Iterable
from types import TracebackType
from typing import Any, Self, TypeAlias

Expand Down Expand Up @@ -284,7 +284,6 @@ async def _set_many(self, values: Iterable[tuple[str, Buffer]]) -> None:
Insert multiple (key, value) pairs into storage.
"""
await gather(*starmap(self.set, values))
return

@property
@abstractmethod
Expand Down Expand Up @@ -330,17 +329,19 @@ def supports_listing(self) -> bool:
...

@abstractmethod
def list(self) -> AsyncGenerator[str, None]:
def list(self) -> AsyncIterator[str]:
"""Retrieve all keys in the store.
Returns
-------
AsyncGenerator[str, None]
AsyncIterator[str]
"""
...
# This method should be async, like overridden methods in child classes.
# However, that's not straightforward:
# https://stackoverflow.com/questions/68905848

@abstractmethod
def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]:
def list_prefix(self, prefix: str) -> AsyncIterator[str]:
"""
Retrieve all keys in the store that begin with a given prefix. Keys are returned relative
to the root of the store.
Expand All @@ -351,12 +352,14 @@ def list_prefix(self, prefix: str) -> AsyncGenerator[str, None]:
Returns
-------
AsyncGenerator[str, None]
AsyncIterator[str]
"""
...
# This method should be async, like overridden methods in child classes.
# However, that's not straightforward:
# https://stackoverflow.com/questions/68905848

@abstractmethod
def list_dir(self, prefix: str) -> AsyncGenerator[str, None]:
def list_dir(self, prefix: str) -> AsyncIterator[str]:
"""
Retrieve all keys and prefixes with a given prefix and which do not contain the character
“/” after the given prefix.
Expand All @@ -367,9 +370,11 @@ def list_dir(self, prefix: str) -> AsyncGenerator[str, None]:
Returns
-------
AsyncGenerator[str, None]
AsyncIterator[str]
"""
...
# This method should be async, like overridden methods in child classes.
# However, that's not straightforward:
# https://stackoverflow.com/questions/68905848

async def delete_dir(self, prefix: str) -> None:
"""
Expand Down
21 changes: 16 additions & 5 deletions src/zarr/api/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from zarr.abc.store import Store
from zarr.core.array import Array, AsyncArray, get_array_metadata
from zarr.core.buffer import NDArrayLike
from zarr.core.common import (
JSON,
AccessModeLiteral,
Expand All @@ -31,7 +32,6 @@
from collections.abc import Iterable

from zarr.abc.codec import Codec
from zarr.core.buffer import NDArrayLike
from zarr.core.chunk_key_encodings import ChunkKeyEncoding

# TODO: this type could use some more thought
Expand Down Expand Up @@ -393,6 +393,8 @@ async def save_array(
_handle_zarr_version_or_format(zarr_version=zarr_version, zarr_format=zarr_format)
or _default_zarr_version()
)
if not isinstance(arr, NDArrayLike):
raise TypeError("arr argument must be numpy or other NDArrayLike array")

mode = kwargs.pop("mode", None)
store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)
Expand Down Expand Up @@ -447,16 +449,26 @@ async def save_group(
or _default_zarr_version()
)

for arg in args:
if not isinstance(arg, NDArrayLike):
raise TypeError(
"All arguments must be numpy or other NDArrayLike arrays (except store, path, storage_options, and zarr_format)"
)
for k, v in kwargs.items():
if not isinstance(v, NDArrayLike):
raise TypeError(f"Keyword argument '{k}' must be a numpy or other NDArrayLike array")

if len(args) == 0 and len(kwargs) == 0:
raise ValueError("at least one array must be provided")
aws = []
for i, arr in enumerate(args):
_path = f"{path}/arr_{i}" if path is not None else f"arr_{i}"
aws.append(
save_array(
store,
arr,
zarr_format=zarr_format,
path=f"{path}/arr_{i}",
path=_path,
storage_options=storage_options,
)
)
Expand Down Expand Up @@ -866,9 +878,8 @@ async def create(
warnings.warn("meta_array is not yet implemented", RuntimeWarning, stacklevel=2)

mode = kwargs.pop("mode", None)
if mode is None:
if not isinstance(store, Store | StorePath):
mode = "a"
if mode is None and not isinstance(store, Store | StorePath):
mode = "a"

store_path = await make_store_path(store, path=path, mode=mode, storage_options=storage_options)

Expand Down
2 changes: 0 additions & 2 deletions src/zarr/codecs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
from zarr.codecs.bytes import BytesCodec, Endian
from zarr.codecs.crc32c_ import Crc32cCodec
from zarr.codecs.gzip import GzipCodec
from zarr.codecs.pipeline import BatchedCodecPipeline
from zarr.codecs.sharding import ShardingCodec, ShardingCodecIndexLocation
from zarr.codecs.transpose import TransposeCodec
from zarr.codecs.vlen_utf8 import VLenBytesCodec, VLenUTF8Codec
from zarr.codecs.zstd import ZstdCodec
from zarr.core.metadata.v3 import DataType

__all__ = [
"BatchedCodecPipeline",
"BloscCname",
"BloscCodec",
"BloscShuffle",
Expand Down
2 changes: 1 addition & 1 deletion src/zarr/codecs/gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
def parse_gzip_level(data: JSON) -> int:
if not isinstance(data, (int)):
raise TypeError(f"Expected int, got {type(data)}")
if data not in range(0, 10):
if data not in range(10):
raise ValueError(
f"Expected an integer from the inclusive range (0, 9). Got {data} instead."
)
Expand Down
Empty file removed src/zarr/codecs/registry.py
Empty file.
2 changes: 1 addition & 1 deletion src/zarr/codecs/sharding.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def create_empty(
def __setitem__(self, chunk_coords: ChunkCoords, value: Buffer) -> None:
chunk_start = len(self.buf)
chunk_length = len(value)
self.buf = self.buf + value
self.buf += value
self.index.set_chunk_slice(chunk_coords, slice(chunk_start, chunk_start + chunk_length))

def __delitem__(self, chunk_coords: ChunkCoords) -> None:
Expand Down
4 changes: 4 additions & 0 deletions src/zarr/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from __future__ import annotations

from zarr.core.buffer import Buffer, NDBuffer # noqa: F401
from zarr.core.codec_pipeline import BatchedCodecPipeline # noqa: F401
Loading

0 comments on commit 7a92479

Please sign in to comment.