Skip to content

Commit cb3e6d8

Browse files
authored
Merge branch 'main' into refactor-open-group
2 parents 74baee4 + e76b1e0 commit cb3e6d8

File tree

13 files changed

+143
-9
lines changed

13 files changed

+143
-9
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Nightly Wheels
2+
3+
on:
4+
schedule:
5+
# Run nightly at 2 AM UTC
6+
- cron: '0 2 * * *'
7+
workflow_dispatch:
8+
9+
jobs:
10+
build_and_upload_nightly:
11+
name: Build and upload nightly wheels
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v5
16+
with:
17+
submodules: true
18+
fetch-depth: 0
19+
20+
- uses: actions/setup-python@v6
21+
name: Install Python
22+
with:
23+
python-version: '3.13'
24+
25+
- name: Install build dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install hatch
29+
30+
- name: Build wheel and sdist
31+
run: hatch build
32+
33+
- name: Upload nightly wheels
34+
uses: scientific-python/upload-nightly-action@b36e8c0c10dbcfd2e05bf95f17ef8c14fd708dbf
35+
with:
36+
artifacts_path: dist
37+
anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }}

changes/3422.bugfix.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix a potential race condition when using :func:`zarr.create_array` with the ``data`` parameter
2+
set to a NumPy array. Previously Zarr was iterating over the newly created array with a granularity
3+
that was too low. Now Zarr chooses a granularity that matches the size of the stored objects for
4+
that array.

changes/3448.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Setting ``fill_value`` to a float like ``0.0`` when the data type of the array is an integer is a common
2+
mistake. This change lets Zarr Python read arrays with this erroneous metadata, although Zarr Python
3+
will not create such arrays.

changes/3449.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Publish nightly wheels to https://anaconda.org/scientific-python-nightly-wheels/.

docs/user-guide/installation.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ Zarr is also published to `conda-forge <https://conda-forge.org>`_. Install it u
4242
Conda does not support optional dependencies, so you will have to manually install any packages
4343
needed to enable extra functionality.
4444

45+
Nightly wheels
46+
--------------
47+
48+
Development wheels are built nightly and published to the `scientific-python-nightly-wheels <https://anaconda.org/scientific-python-nightly-wheels>`_ index. To install the latest nightly build:
49+
50+
.. code-block:: console
51+
52+
$ pip install --pre \
53+
--extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
54+
zarr
55+
56+
Note that nightly wheels may be unstable and are intended for testing purposes.
57+
4558
Dependency support
4659
------------------
4760
Zarr has endorsed `Scientific-Python SPEC 0 <https://scientific-python.org/specs/spec-0000/>`_ and now follows the version support window as outlined below:

src/zarr/api/asynchronous.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,23 @@ async def consolidate_metadata(
250250

251251

252252
async def copy(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
253+
"""
254+
Not implemented.
255+
"""
253256
raise NotImplementedError
254257

255258

256259
async def copy_all(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
260+
"""
261+
Not implemented.
262+
"""
257263
raise NotImplementedError
258264

259265

260266
async def copy_store(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
267+
"""
268+
Not implemented.
269+
"""
261270
raise NotImplementedError
262271

263272

src/zarr/api/synchronous.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,23 @@ def consolidate_metadata(
112112

113113

114114
def copy(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
115+
"""
116+
Not implemented.
117+
"""
115118
return sync(async_api.copy(*args, **kwargs))
116119

117120

118121
def copy_all(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
122+
"""
123+
Not implemented.
124+
"""
119125
return sync(async_api.copy_all(*args, **kwargs))
120126

121127

122128
def copy_store(*args: Any, **kwargs: Any) -> tuple[int, int, int]:
129+
"""
130+
Not implemented.
131+
"""
123132
return sync(async_api.copy_store(*args, **kwargs))
124133

125134

src/zarr/core/array.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4421,7 +4421,7 @@ async def _copy_arraylike_region(chunk_coords: slice, _data: NDArrayLike) -> Non
44214421

44224422
# Stream data from the source array to the new array
44234423
await concurrent_map(
4424-
[(region, data) for region in result._iter_chunk_regions()],
4424+
[(region, data) for region in result._iter_shard_regions()],
44254425
_copy_arraylike_region,
44264426
zarr.core.config.config.get("async.concurrency"),
44274427
)

src/zarr/core/dtype/npy/common.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Any,
1010
Final,
1111
Literal,
12+
NewType,
1213
SupportsComplex,
1314
SupportsFloat,
1415
SupportsIndex,
@@ -54,6 +55,9 @@
5455
"generic",
5556
)
5657

58+
IntishFloat = NewType("IntishFloat", float)
59+
"""A type for floats that represent integers, like 1.0 (but not 1.1)."""
60+
5761
NumpyEndiannessStr = Literal[">", "<", "="]
5862
NUMPY_ENDIANNESS_STR: Final = ">", "<", "="
5963

@@ -467,6 +471,23 @@ def check_json_int(data: JSON) -> TypeGuard[int]:
467471
return bool(isinstance(data, int))
468472

469473

474+
def check_json_intish_float(data: JSON) -> TypeGuard[IntishFloat]:
475+
"""
476+
Check if a JSON value is an "intish float", i.e. a float that represents an integer, like 0.0.
477+
478+
Parameters
479+
----------
480+
data : JSON
481+
The JSON value to check.
482+
483+
Returns
484+
-------
485+
Bool
486+
True if the data is an intish float, False otherwise.
487+
"""
488+
return isinstance(data, float) and data.is_integer()
489+
490+
470491
def check_json_str(data: JSON) -> TypeGuard[str]:
471492
"""
472493
Check if a JSON value is a string.

src/zarr/core/dtype/npy/int.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
)
2626
from zarr.core.dtype.npy.common import (
2727
check_json_int,
28+
check_json_intish_float,
2829
endianness_to_numpy_str,
2930
get_endianness_from_numpy_dtype,
3031
)
@@ -206,6 +207,8 @@ def from_json_scalar(self, data: JSON, *, zarr_format: ZarrFormat) -> TIntScalar
206207
"""
207208
if check_json_int(data):
208209
return self._cast_scalar_unchecked(data)
210+
if check_json_intish_float(data):
211+
return self._cast_scalar_unchecked(int(data))
209212
raise TypeError(f"Invalid type: {data}. Expected an integer.")
210213

211214
def to_json_scalar(self, data: object, *, zarr_format: ZarrFormat) -> int:

0 commit comments

Comments
 (0)