Skip to content

Commit 8d948d1

Browse files
authored
Merge branch 'main' into numpy==2.1
2 parents 0b00b8e + eb1b6e8 commit 8d948d1

File tree

16 files changed

+194
-371
lines changed

16 files changed

+194
-371
lines changed

.github/workflows/check_changelogs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
1313

1414
- name: Install uv
15-
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
15+
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
1616

1717
- name: Check changelog entries
1818
run: uv run --no-sync python ci/check_changelog_entries.py

.github/workflows/releases.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
pip install hatch
2828
- name: Build wheel and sdist
2929
run: hatch build
30-
- uses: actions/upload-artifact@v4
30+
- uses: actions/upload-artifact@v5
3131
with:
3232
name: releases
3333
path: dist
@@ -36,7 +36,7 @@ jobs:
3636
needs: [build_artifacts]
3737
runs-on: ubuntu-latest
3838
steps:
39-
- uses: actions/download-artifact@v5
39+
- uses: actions/download-artifact@v6
4040
with:
4141
name: releases
4242
path: dist
@@ -51,7 +51,7 @@ jobs:
5151
runs-on: ubuntu-latest
5252
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
5353
steps:
54-
- uses: actions/download-artifact@v5
54+
- uses: actions/download-artifact@v6
5555
with:
5656
name: releases
5757
path: dist

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ci:
66
default_stages: [pre-commit, pre-push]
77
repos:
88
- repo: https://github.com/astral-sh/ruff-pre-commit
9-
rev: v0.13.3
9+
rev: v0.14.3
1010
hooks:
1111
- id: ruff-check
1212
args: ["--fix", "--show-fixes"]
@@ -42,7 +42,7 @@ repos:
4242
- hypothesis
4343
- s3fs
4444
- repo: https://github.com/scientific-python/cookie
45-
rev: 2025.10.01
45+
rev: 2025.10.20
4646
hooks:
4747
- id: sp-repo-review
4848
- repo: https://github.com/pre-commit/pygrep-hooks

changes/3533.misc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reduced the runtime of the test suite by simplifying test cases.

changes/3545.misc.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

changes/3553.misc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Changes the internal logic of the `BloscCodec` class to ensure that the `typesize` and `shuffle` parameters are not set to `None` when creating a new instance of `BloscCodec`.

changes/3560.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve write performance to large shards by up to 10x.

src/zarr/codecs/blosc.py

Lines changed: 18 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from __future__ import annotations
22

33
import asyncio
4-
import warnings
5-
from dataclasses import dataclass, replace
4+
from dataclasses import dataclass, field, replace
65
from enum import Enum
76
from functools import cached_property
87
from typing import TYPE_CHECKING, Final, Literal, NotRequired, TypedDict
@@ -15,7 +14,6 @@
1514
from zarr.core.buffer.cpu import as_numpy_array_wrapper
1615
from zarr.core.common import JSON, NamedRequiredConfig, parse_enum, parse_named_configuration
1716
from zarr.core.dtype.common import HasItemSize
18-
from zarr.errors import ZarrDeprecationWarning
1917

2018
if TYPE_CHECKING:
2119
from typing import Self
@@ -131,12 +129,6 @@ class BloscCodec(BytesBytesCodec):
131129
132130
Attributes
133131
----------
134-
tunable_attrs : set of {'typesize', 'shuffle'}
135-
Attributes that will be automatically tuned when `evolve_from_array_spec()`
136-
is called. By default, contains {'typesize', 'shuffle'}. When either
137-
`typesize` or `shuffle` is explicitly set to None during initialization,
138-
the corresponding attribute is added to this set (if not already present),
139-
allowing it to be overridden based on the array's dtype.
140132
is_fixed_size : bool
141133
Always False for Blosc codec, as compression produces variable-sized output.
142134
typesize : int
@@ -154,8 +146,8 @@ class BloscCodec(BytesBytesCodec):
154146
----------
155147
typesize : int, optional
156148
The data type size in bytes. This affects how the shuffle filter processes
157-
the data. If None (deprecated), defaults to 1 and the attribute is marked
158-
as tunable. Default: 1.
149+
the data. If None, defaults to 1 and the attribute is marked as tunable.
150+
Default: 1.
159151
cname : BloscCname or {'lz4', 'lz4hc', 'blosclz', 'snappy', 'zlib', 'zstd'}, optional
160152
The compression algorithm to use. Default: 'zstd'.
161153
clevel : int, optional
@@ -168,47 +160,17 @@ class BloscCodec(BytesBytesCodec):
168160
- 'shuffle': Byte shuffling (better for typesize > 1)
169161
- 'bitshuffle': Bit shuffling (better for typesize == 1)
170162
171-
If None (deprecated), defaults to 'bitshuffle' and the attribute is marked
163+
If None, defaults to 'bitshuffle' and the attribute is marked
172164
as tunable. Default: 'bitshuffle'.
173165
blocksize : int, optional
174166
The requested size of compressed blocks in bytes. A value of 0 means
175167
automatic block size selection. Default: 0.
176-
tunable_attrs : set of {'typesize', 'shuffle'}, optional
177-
Names of attributes that can be automatically adjusted by
178-
`evolve_from_array_spec()`. This allows the codec to adapt its parameters
179-
based on the array's data type when the array is created. If None, defaults
180-
to {'typesize', 'shuffle'}.
181168
182169
Notes
183170
-----
184-
**Tunable Attributes Logic**:
185-
186-
The `tunable_attrs` mechanism allows codec parameters to be automatically
187-
adjusted based on the array's data type:
188-
189-
1. **Initialization**: During `__init__`, if `tunable_attrs` is None, it
190-
defaults to {'typesize', 'shuffle'}. This means both attributes can be
191-
tuned by default.
192-
193-
2. **Deprecated None Values**: If `typesize` or `shuffle` is explicitly set
194-
to None:
195-
196-
- A deprecation warning is issued
197-
- The parameter is set to a default value (1 for typesize, 'bitshuffle'
198-
for shuffle)
199-
- The attribute name is added to `tunable_attrs`
200-
201-
3. **Evolution**: When `evolve_from_array_spec()` is called (typically during
202-
array creation), it creates a new codec instance with updated parameters:
203-
204-
- If 'typesize' is in `tunable_attrs`, it's set to the array dtype's
205-
item size
206-
- If 'shuffle' is in `tunable_attrs`, it's set to 'bitshuffle' if
207-
item_size == 1, otherwise 'shuffle'
208-
209-
4. **Explicit Values**: If you explicitly set `typesize=4` or
210-
`shuffle='noshuffle'`, these values are NOT in `tunable_attrs` by default
211-
and will not be changed by `evolve_from_array_spec()`.
171+
**Tunable attributes**: If `typesize` or `shuffle` are set to None during
172+
initialization, they are marked as tunable attributes. This means they can be
173+
adjusted later based on the data type of the array being compressed.
212174
213175
**Thread Safety**: This codec sets `numcodecs.blosc.use_threads = False` at
214176
module import time to avoid threading issues in asyncio contexts.
@@ -229,28 +191,14 @@ class BloscCodec(BytesBytesCodec):
229191
>>> codec.cname
230192
<BloscCname.zstd: 'zstd'>
231193
232-
Use deprecated None values (will be tuned automatically):
233-
234-
>>> codec = BloscCodec(typesize=None, shuffle=None) # doctest: +SKIP
235-
DeprecationWarning: The typesize parameter was set to None...
236-
>>> 'typesize' in codec.tunable_attrs
237-
True
238-
>>> 'shuffle' in codec.tunable_attrs
239-
True
240-
241-
Prevent automatic tuning:
242-
243-
>>> codec = BloscCodec(typesize=4, shuffle='noshuffle', tunable_attrs=set())
244-
>>> codec.tunable_attrs
245-
set()
246-
247194
See Also
248195
--------
249196
BloscShuffle : Enum for shuffle filter options
250197
BloscCname : Enum for compression algorithm options
251198
"""
252199

253-
tunable_attrs: set[Literal["typesize", "shuffle"]]
200+
# This attribute tracks parameters were set to None at init time, and thus tunable
201+
_tunable_attrs: set[Literal["typesize", "shuffle"]] = field(init=False)
254202
is_fixed_size = False
255203

256204
typesize: int
@@ -262,41 +210,25 @@ class BloscCodec(BytesBytesCodec):
262210
def __init__(
263211
self,
264212
*,
265-
typesize: int | None = 1,
213+
typesize: int | None = None,
266214
cname: BloscCname | CName = BloscCname.zstd,
267215
clevel: int = 5,
268-
shuffle: BloscShuffle | Shuffle | None = "bitshuffle",
216+
shuffle: BloscShuffle | Shuffle | None = None,
269217
blocksize: int = 0,
270-
tunable_attrs: set[Literal["typesize", "shuffle"]] | None = None,
271218
) -> None:
272-
# set default value of tunable_attrs
273-
if tunable_attrs is None:
274-
object.__setattr__(self, "tunable_attrs", {"typesize", "shuffle"})
275-
else:
276-
object.__setattr__(self, "tunable_attrs", tunable_attrs)
219+
object.__setattr__(self, "_tunable_attrs", set())
277220

278-
# If typesize was set to None: warn, replace it with a valid typesize
221+
# If typesize was set to None, replace it with a valid typesize
279222
# and flag the typesize attribute as safe to replace later
280223
if typesize is None:
281-
msg = (
282-
"The typesize parameter was set to None. This is deprecated. "
283-
"Provide a positive int for the typesize parameter instead. "
284-
)
285-
warnings.warn(msg, ZarrDeprecationWarning, stacklevel=2)
286224
typesize = 1
287-
self.tunable_attrs.update({"typesize"})
225+
self._tunable_attrs.update({"typesize"})
288226

289-
# If shuffle was set to None: warn, replace it with a valid typesize
227+
# If shuffle was set to None, replace it with a valid shuffle
290228
# and flag the shuffle attribute as safe to replace later
291229
if shuffle is None:
292-
msg = (
293-
"The shuffle parameter was set to None. This is deprecated. "
294-
"Provide a valid shuffle literal string -- "
295-
f"one of {SHUFFLE!r} -- instead."
296-
)
297-
warnings.warn(msg, ZarrDeprecationWarning, stacklevel=2)
298230
shuffle = BloscShuffle.bitshuffle
299-
self.tunable_attrs.update({"shuffle"})
231+
self._tunable_attrs.update({"shuffle"})
300232

301233
typesize_parsed = parse_typesize(typesize)
302234
cname_parsed = parse_enum(cname, BloscCname)
@@ -339,9 +271,9 @@ def evolve_from_array_spec(self, array_spec: ArraySpec) -> Self:
339271
if isinstance(array_spec.dtype, HasItemSize):
340272
item_size = array_spec.dtype.item_size
341273
new_codec = self
342-
if "typesize" in self.tunable_attrs:
274+
if "typesize" in self._tunable_attrs:
343275
new_codec = replace(new_codec, typesize=item_size)
344-
if "shuffle" in self.tunable_attrs:
276+
if "shuffle" in self._tunable_attrs:
345277
new_codec = replace(
346278
new_codec,
347279
shuffle=(BloscShuffle.bitshuffle if item_size == 1 else BloscShuffle.shuffle),

0 commit comments

Comments
 (0)