Skip to content

Commit

Permalink
Merge branch 'main' into doc/update-contributor-guide
Browse files Browse the repository at this point in the history
  • Loading branch information
dstansby authored Dec 5, 2024
2 parents ae4ac1a + ae6e8e6 commit 0ab320e
Show file tree
Hide file tree
Showing 20 changed files with 769 additions and 503 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,22 @@ jobs:
- name: Run Tests
run: |
hatch env run --env ${{ matrix.dependency-set }} run
test-complete:
name: Test complete

needs:
[
test,
test-upstream-and-min-deps,
]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check failure
if: |
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: exit 1
- name: Success
run: echo Success!
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ default_language_version:
python: python3
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
rev: v0.8.1
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand Down
8 changes: 2 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ gpu = [
docs = [
'sphinx==8.1.3',
'sphinx-autobuild>=2021.3.14',
'sphinx-autoapi==3.3.3',
'sphinx-autoapi==3.4.0',
'sphinx_design',
'sphinx-issues',
'sphinx-copybutton',
Expand Down Expand Up @@ -294,19 +294,14 @@ extend-select = [
"W", # pycodestyle warnings
]
ignore = [
"ANN101", # deprecated
"ANN102", # deprecated
"ANN401",
"PT004", # deprecated
"PT005", # deprecated
"PT011", # TODO: apply this rule
"PT012", # TODO: apply this rule
"RET505",
"RET506",
"RUF005",
"SIM108",
"TRY003",
"UP027", # deprecated
"UP038", # https://github.com/astral-sh/ruff/issues/7871
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
"W191",
Expand Down Expand Up @@ -347,6 +342,7 @@ ignore_errors = true

[[tool.mypy.overrides]]
module = [
"zarr.testing.stateful", # lots of hypothesis decorator errors
"tests.package_with_entrypoint.*",
"tests.test_codecs.test_codecs",
"tests.test_codecs.test_transpose",
Expand Down
6 changes: 3 additions & 3 deletions src/zarr/api/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,12 +653,12 @@ async def open_group(
Store or path to directory in file system or name of zip file.
Strings are interpreted as paths on the local file system
and used as the ``root`` argument to :class:`zarr.store.LocalStore`.
and used as the ``root`` argument to :class:`zarr.storage.LocalStore`.
Dictionaries are used as the ``store_dict`` argument in
:class:`zarr.store.MemoryStore``.
:class:`zarr.storage.MemoryStore``.
By default (``store=None``) a new :class:`zarr.store.MemoryStore`
By default (``store=None``) a new :class:`zarr.storage.MemoryStore`
is created.
mode : {'r', 'r+', 'a', 'w', 'w-'}, optional
Expand Down
6 changes: 5 additions & 1 deletion src/zarr/codecs/_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import TYPE_CHECKING

import numcodecs
from numcodecs.compat import ensure_ndarray_like
from numcodecs.compat import ensure_bytes, ensure_ndarray_like

from zarr.abc.codec import ArrayBytesCodec
from zarr.registry import get_ndbuffer_class
Expand Down Expand Up @@ -68,6 +68,9 @@ async def _encode_single(
) -> Buffer | None:
chunk = chunk_array.as_ndarray_like()

# ensure contiguous and correct order
chunk = chunk.astype(chunk_spec.dtype, order=chunk_spec.order, copy=False)

# apply filters
if self.filters:
for f in self.filters:
Expand All @@ -83,6 +86,7 @@ async def _encode_single(
else:
cdata = chunk

cdata = ensure_bytes(cdata)
return chunk_spec.prototype.buffer.from_bytes(cdata)

def compute_encoded_size(self, _input_byte_length: int, _chunk_spec: ArraySpec) -> int:
Expand Down
61 changes: 53 additions & 8 deletions src/zarr/core/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,18 +1346,53 @@ def info(self) -> Any:
AsyncArray.info_complete
All information about a group, including dynamic information
like the number of bytes and chunks written.
Examples
--------
>>> arr = await zarr.api.asynchronous.create(
... path="array", shape=(3, 4, 5), chunks=(2, 2, 2))
... )
>>> arr.info
Type : Array
Zarr format : 3
Data type : DataType.float64
Shape : (3, 4, 5)
Chunk shape : (2, 2, 2)
Order : C
Read-only : False
Store type : MemoryStore
Codecs : [{'endian': <Endian.little: 'little'>}]
No. bytes : 480
"""
return self._info()

async def info_complete(self) -> Any:
# TODO: get the size of the object from the store.
extra = {
"count_chunks_initialized": await self.nchunks_initialized(),
# count_bytes_stored isn't yet implemented.
}
return self._info(extra=extra)

def _info(self, extra: dict[str, int] | None = None) -> Any:
"""
Return all the information for an array, including dynamic information like a storage size.
In addition to the static information, this provides
- The count of chunks initialized
- The sum of the bytes written
Returns
-------
ArrayInfo
See Also
--------
AsyncArray.info
A property giving just the statically known information about an array.
"""
return self._info(
await self.nchunks_initialized(),
await self.store_path.store.getsize_prefix(self.store_path.path),
)

def _info(
self, count_chunks_initialized: int | None = None, count_bytes_stored: int | None = None
) -> Any:
kwargs: dict[str, Any] = {}
if self.metadata.zarr_format == 2:
assert isinstance(self.metadata, ArrayV2Metadata)
Expand Down Expand Up @@ -1386,6 +1421,8 @@ def _info(self, extra: dict[str, int] | None = None) -> Any:
_read_only=self.read_only,
_store_type=type(self.store_path.store).__name__,
_count_bytes=self.dtype.itemsize * self.size,
_count_bytes_stored=count_bytes_stored,
_count_chunks_initialized=count_chunks_initialized,
**kwargs,
)

Expand Down Expand Up @@ -2844,6 +2881,14 @@ def set_coordinate_selection(
if hasattr(value, "shape") and len(value.shape) > 1:
value = np.array(value).reshape(-1)

if not is_scalar(value, self.dtype) and (
isinstance(value, NDArrayLike) and indexer.shape != value.shape
):
raise ValueError(
f"Attempting to set a selection of {indexer.sel_shape[0]} "
f"elements with an array of {value.shape[0]} elements."
)

sync(self._async_array._set_selection(indexer, value, fields=fields, prototype=prototype))

@_deprecate_positional_args
Expand Down
8 changes: 7 additions & 1 deletion src/zarr/core/buffer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ def reshape(

def view(self, dtype: npt.DTypeLike) -> Self: ...

def astype(self, dtype: npt.DTypeLike, order: Literal["K", "A", "C", "F"] = ...) -> Self: ...
def astype(
self,
dtype: npt.DTypeLike,
order: Literal["K", "A", "C", "F"] = ...,
*,
copy: bool = ...,
) -> Self: ...

def fill(self, value: Any) -> None: ...

Expand Down
4 changes: 2 additions & 2 deletions src/zarr/core/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ async def from_store(
async def open(
cls,
store: StoreLike,
zarr_format: Literal[2, 3, None] = 3,
zarr_format: Literal[2, 3] | None = 3,
use_consolidated: bool | str | None = None,
) -> AsyncGroup:
"""Open a new AsyncGroup
Expand Down Expand Up @@ -1691,7 +1691,7 @@ def from_store(
def open(
cls,
store: StoreLike,
zarr_format: Literal[2, 3, None] = 3,
zarr_format: Literal[2, 3] | None = 3,
) -> Group:
"""Open a group from an initialized store.
Expand Down
11 changes: 9 additions & 2 deletions src/zarr/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,8 +1346,15 @@ def decode_morton(z: int, chunk_shape: ChunkCoords) -> ChunkCoords:


def morton_order_iter(chunk_shape: ChunkCoords) -> Iterator[ChunkCoords]:
for i in range(product(chunk_shape)):
yield decode_morton(i, chunk_shape)
i = 0
order: list[ChunkCoords] = []
while len(order) < product(chunk_shape):
m = decode_morton(i, chunk_shape)
if m not in order and all(x < y for x, y in zip(m, chunk_shape, strict=False)):
order.append(m)
i += 1
for j in range(product(chunk_shape)):
yield order[j]


def c_order_iter(chunks_per_shard: ChunkCoords) -> Iterator[ChunkCoords]:
Expand Down
2 changes: 0 additions & 2 deletions src/zarr/storage/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from zarr.storage.local import LocalStore
from zarr.storage.memory import MemoryStore

# from zarr.store.remote import RemoteStore

if TYPE_CHECKING:
from zarr.core.buffer import BufferPrototype

Expand Down
Loading

0 comments on commit 0ab320e

Please sign in to comment.