Skip to content

Commit d2e1978

Browse files
committed
Merge branch 'v3' of https://github.com/zarr-developers/zarr-python into chore/drop-py310-np124
2 parents 4a7b176 + e968ac5 commit d2e1978

File tree

624 files changed

+670
-29551
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

624 files changed

+670
-29551
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ contact_links:
33
- name: ✨ Propose a new major feature
44
url: https://github.com/zarr-developers/zarr-specs
55
about: A new major feature should be discussed in the Zarr specifications repository.
6-
- name: ❓ Discuss something on gitter
7-
url: https://gitter.im/zarr-developers/community
8-
about: For questions like "How do I do X with Zarr?", you can move to our Gitter channel.
6+
- name: ❓ Discuss something on ZulipChat
7+
url: https://ossci.zulipchat.com/
8+
about: For questions like "How do I do X with Zarr?", you can move to our ZulipChat.
99
- name: ❓ Discuss something on GitHub Discussions
1010
url: https://github.com/zarr-developers/zarr-python/discussions
1111
about: For questions like "How do I do X with Zarr?", you can move to GitHub Discussions.

.github/workflows/releases.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
with:
5656
name: releases
5757
path: dist
58-
- uses: pypa/[email protected].1
58+
- uses: pypa/[email protected].2
5959
with:
6060
user: __token__
6161
password: ${{ secrets.pypi_password }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,5 @@ fixture/
8484
.DS_Store
8585
tests/.hypothesis
8686
.hypothesis/
87+
88+
zarr/version.py

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ default_language_version:
77
python: python3
88
repos:
99
- repo: https://github.com/astral-sh/ruff-pre-commit
10-
rev: v0.6.5
10+
rev: v0.6.7
1111
hooks:
1212
- id: ruff
1313
args: ["--fix", "--show-fixes"]

bench/compress_normal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
a,
1717
chunks=1000000,
1818
compression="blosc",
19-
compression_opts=dict(cname="lz4", clevel=5, shuffle=2),
19+
compression_opts={"cname": "lz4", "clevel": 5, "shuffle": 2},
2020
)
2121
print(z)
2222

pyproject.toml

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,18 +206,45 @@ extend-exclude = [
206206

207207
[tool.ruff.lint]
208208
extend-select = [
209-
"B", # flake8-bugbear
210-
"I", # isort
211-
"ISC",
212-
"UP", # pyupgrade
213-
"RSE",
209+
"B", # flake8-bugbear
210+
"C4", # flake8-comprehensions
211+
"FLY", # flynt
212+
"I", # isort
213+
"ISC", # flake8-implicit-str-concat
214+
"PGH", # pygrep-hooks
215+
"PT", # flake8-pytest-style
216+
"PYI", # flake8-pyi
217+
"RSE", # flake8-raise
218+
"RET", # flake8-return
214219
"RUF",
215220
"TCH", # flake8-type-checking
216221
"TRY", # tryceratops
222+
"UP", # pyupgrade
217223
]
218224
ignore = [
225+
"PT004", # deprecated
226+
"PT011", # TODO: apply this rule
227+
"PT012", # TODO: apply this rule
228+
"PYI013",
229+
"RET505",
230+
"RET506",
219231
"RUF005",
220232
"TRY003",
233+
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
234+
"W191",
235+
"E111",
236+
"E114",
237+
"E117",
238+
"D206",
239+
"D300",
240+
"Q000",
241+
"Q001",
242+
"Q002",
243+
"Q003",
244+
"COM812",
245+
"COM819",
246+
"ISC001",
247+
"ISC002",
221248
]
222249

223250
[tool.mypy]
@@ -273,6 +300,7 @@ filterwarnings = [
273300
"ignore:PY_SSIZE_T_CLEAN will be required.*:DeprecationWarning",
274301
"ignore:The loop argument is deprecated since Python 3.8.*:DeprecationWarning",
275302
"ignore:Creating a zarr.buffer.gpu.*:UserWarning",
303+
"ignore:Duplicate name:UserWarning", # from ZipFile
276304
]
277305
markers = [
278306
"gpu: mark a test as requiring CuPy and GPU"

src/zarr/abc/store.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from abc import ABC, abstractmethod
22
from asyncio import gather
33
from collections.abc import AsyncGenerator, Iterable
4+
from types import TracebackType
45
from typing import Any, NamedTuple, Protocol, Self, runtime_checkable
56

67
from zarr.core.buffer import Buffer, BufferPrototype
@@ -33,7 +34,7 @@ class Store(ABC):
3334
_mode: AccessMode
3435
_is_open: bool
3536

36-
def __init__(self, mode: AccessModeLiteral = "r", *args: Any, **kwargs: Any):
37+
def __init__(self, mode: AccessModeLiteral = "r", *args: Any, **kwargs: Any) -> None:
3738
self._is_open = False
3839
self._mode = AccessMode.from_literal(mode)
3940

@@ -47,7 +48,12 @@ def __enter__(self) -> Self:
4748
"""Enter a context manager that will close the store upon exiting."""
4849
return self
4950

50-
def __exit__(self, *args: Any) -> None:
51+
def __exit__(
52+
self,
53+
exc_type: type[BaseException] | None,
54+
exc_value: BaseException | None,
55+
traceback: TracebackType | None,
56+
) -> None:
5157
"""Close the store."""
5258
self.close()
5359

@@ -162,7 +168,7 @@ async def _set_many(self, values: Iterable[tuple[str, Buffer]]) -> None:
162168
Insert multiple (key, value) pairs into storage.
163169
"""
164170
await gather(*(self.set(key, value) for key, value in values))
165-
return None
171+
return
166172

167173
@property
168174
@abstractmethod

src/zarr/api/asynchronous.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import asyncio
44
import warnings
5-
from typing import TYPE_CHECKING, Any, Literal, Union, cast
5+
from typing import TYPE_CHECKING, Any, Literal, cast
66

77
import numpy as np
88
import numpy.typing as npt
@@ -25,6 +25,10 @@
2525
from zarr.core.buffer import NDArrayLike
2626
from zarr.core.chunk_key_encodings import ChunkKeyEncoding
2727

28+
# TODO: this type could use some more thought
29+
ArrayLike = AsyncArray | Array | npt.NDArray[Any]
30+
PathLike = str
31+
2832
__all__ = [
2933
"consolidate_metadata",
3034
"copy",
@@ -53,10 +57,6 @@
5357
"zeros_like",
5458
]
5559

56-
# TODO: this type could use some more thought, noqa to avoid "Variable "asynchronous.ArrayLike" is not valid as a type"
57-
ArrayLike = Union[AsyncArray | Array | npt.NDArray[Any]] # noqa
58-
PathLike = str
59-
6060

6161
def _get_shape_chunks(a: ArrayLike | Any) -> tuple[ChunkCoords | None, ChunkCoords | None]:
6262
"""helper function to get the shape and chunks from an array-like object"""

src/zarr/codecs/_v2.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@
88

99
from zarr.abc.codec import ArrayArrayCodec, ArrayBytesCodec
1010
from zarr.core.buffer import Buffer, NDBuffer, default_buffer_prototype
11-
from zarr.core.common import JSON, to_thread
11+
from zarr.core.common import to_thread
1212
from zarr.registry import get_ndbuffer_class
1313

1414
if TYPE_CHECKING:
15+
import numcodecs.abc
16+
1517
from zarr.core.array_spec import ArraySpec
1618

1719

1820
@dataclass(frozen=True)
1921
class V2Compressor(ArrayBytesCodec):
20-
compressor: dict[str, JSON] | None
22+
compressor: numcodecs.abc.Codec | None
2123

2224
is_fixed_size = False
2325

@@ -27,9 +29,8 @@ async def _decode_single(
2729
chunk_spec: ArraySpec,
2830
) -> NDBuffer:
2931
if self.compressor is not None:
30-
compressor = numcodecs.get_codec(self.compressor)
3132
chunk_numpy_array = ensure_ndarray(
32-
await to_thread(compressor.decode, chunk_bytes.as_array_like())
33+
await to_thread(self.compressor.decode, chunk_bytes.as_array_like())
3334
)
3435
else:
3536
chunk_numpy_array = ensure_ndarray(chunk_bytes.as_array_like())
@@ -47,14 +48,13 @@ async def _encode_single(
4748
) -> Buffer | None:
4849
chunk_numpy_array = chunk_array.as_numpy_array()
4950
if self.compressor is not None:
50-
compressor = numcodecs.get_codec(self.compressor)
5151
if (
5252
not chunk_numpy_array.flags.c_contiguous
5353
and not chunk_numpy_array.flags.f_contiguous
5454
):
5555
chunk_numpy_array = chunk_numpy_array.copy(order="A")
5656
encoded_chunk_bytes = ensure_bytes(
57-
await to_thread(compressor.encode, chunk_numpy_array)
57+
await to_thread(self.compressor.encode, chunk_numpy_array)
5858
)
5959
else:
6060
encoded_chunk_bytes = ensure_bytes(chunk_numpy_array)

src/zarr/codecs/sharding.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def is_dense(self, chunk_byte_length: int) -> bool:
150150

151151
# Are all non-empty offsets unique?
152152
if len(
153-
set(offset for offset, _ in sorted_offsets_and_lengths if offset != MAX_UINT_64)
153+
{offset for offset, _ in sorted_offsets_and_lengths if offset != MAX_UINT_64}
154154
) != len(sorted_offsets_and_lengths):
155155
return False
156156

@@ -379,8 +379,8 @@ def to_dict(self) -> dict[str, JSON]:
379379
"name": "sharding_indexed",
380380
"configuration": {
381381
"chunk_shape": self.chunk_shape,
382-
"codecs": tuple([s.to_dict() for s in self.codecs]),
383-
"index_codecs": tuple([s.to_dict() for s in self.index_codecs]),
382+
"codecs": tuple(s.to_dict() for s in self.codecs),
383+
"index_codecs": tuple(s.to_dict() for s in self.index_codecs),
384384
"index_location": self.index_location.value,
385385
},
386386
}
@@ -476,7 +476,7 @@ async def _decode_partial_single(
476476
)
477477

478478
indexed_chunks = list(indexer)
479-
all_chunk_coords = set(chunk_coords for chunk_coords, _, _ in indexed_chunks)
479+
all_chunk_coords = {chunk_coords for chunk_coords, _, _ in indexed_chunks}
480480

481481
# reading bytes of all requested chunks
482482
shard_dict: ShardMapping = {}

0 commit comments

Comments
 (0)