Skip to content

Commit 4b95cdb

Browse files
committed
Getting ready for release 4.4.2
1 parent d561f45 commit 4b95cdb

4 files changed

Lines changed: 124 additions & 54 deletions

File tree

ANNOUNCE.rst

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,57 @@
1-
Announcing Python-Blosc2 4.4.1
1+
Announcing Python-Blosc2 4.4.2
22
==============================
33

4-
We are happy to announce this feature release that brings an interactive
5-
TUI data viewer, automatic SUMMARY indexes for fast WHERE queries,
6-
chunk-aligned Arrow/Parquet imports, expanded ``where()`` acceleration, and a
7-
range of CTable ergonomics and performance improvements.
4+
We are happy to announce this feature and maintenance release that promotes
5+
DSL kernels to first-class CTable computed columns, adds a convenient new
6+
column-assignment API, speeds up bulk NDArray writes, and fixes several
7+
correctness issues.
88

99
The main highlights are:
1010

11-
- **New ``b2view`` interactive viewer**: a terminal-based viewer for all blosc2
12-
containers (``NDArray``, ``CTable``, ``SChunk``, ``BatchArray``, …), launched
13-
with ``b2view <file>`` or ``blosc2.b2view()``. Supports full 1-D/2-D/N-D
14-
browsing, ``CTable`` row navigation, a vlmeta pane, and keyboard shortcuts.
11+
- **DSL kernels as first-class CTable columns**: ``@blosc2.jit``-decorated
12+
functions can now back virtual computed columns, stored generated columns,
13+
and ``where()`` filter predicates directly — in addition to the existing
14+
string-expression form. Columns survive save/open round-trips via
15+
persisted source.
1516

16-
- **Automatic SUMMARY indexes**: when a ``CTable`` is closed after writing,
17-
SUMMARY indexes (per-block min/max) are built by default for all eligible
18-
scalar columns. They are accumulated *incrementally* during writes so the
19-
close step adds almost no extra cost. At query time, a block-skip prefilter
20-
uses these bitmaps to skip blocks that cannot satisfy the WHERE predicate,
21-
reducing decompression work for selective queries.
17+
- **New ``t["col"] = arr`` assignment**: a clean shorthand for overwriting all
18+
live rows of a column. Accepts any array-like, including ``blosc2.NDArray``.
2219

23-
- **Chunk-aligned Arrow/Parquet imports**: fixed-size columns are now written on
24-
a shared chunk/block grid and incoming batches are buffered to exact chunk
25-
boundaries, so every chunk is compressed exactly once. Dictionary columns are
26-
imported in bulk. A new ``--reduce-mem`` CLI flag caps Arrow read-batch size
27-
for memory-constrained nested imports.
20+
- **Chunked NDArray writes**: passing a ``blosc2.NDArray`` to ``extend()`` or
21+
``col[:] = arr`` now decompresses one chunk at a time instead of loading
22+
the entire array into memory, keeping peak RSS bounded for large columns.
2823

29-
- **``where()`` and miniexpr acceleration**: single- and two-argument ``where``
30-
calls are now dispatched directly to miniexpr, avoiding numexpr overhead.
31-
Sparse boolean masks trigger a fast gather path, and a new pre-check skips
32-
per-chunk numexpr setup when the condition is trivially true or false.
24+
- **``BLOSC_ME_JIT`` full override**: the environment variable now takes
25+
unconditional priority over both ``jit=`` and ``jit_backend=`` keyword
26+
arguments, making backend switching from the command line effortless.
3327

34-
- **``CTable.copy()`` enhancements**: a new C-level bulk copy path
35-
(``chunk_copy()``) transfers pre-compressed chunks without
36-
serialization/recompression. ``copy()`` now accepts ``chunks``, ``blocks``,
37-
and ``cparams`` overrides; the ``parquet-to-blosc2`` CLI gains ``--chunks``
38-
and ``--blocks`` flags.
28+
- **Correctness fixes**: a ``None == None`` guard bug that could corrupt rows
29+
when writing to a view-backed column via the NDArray fast path; a missing
30+
view guard in the new ``__setitem__``; and the fast path being silently
31+
disabled for disk-opened tables have all been fixed.
3932

40-
- **``sort_by()`` on views is now lazy**: sorting a filtered view returns a
41-
position-reordered view whose columns are read in sorted order without a full
42-
materialization pass.
33+
A quick example of the new DSL computed column API::
4334

44-
- **``context manager`` support for ``blosc2.open()``**: all objects returned by
45-
``blosc2.open()`` now support the ``with`` statement for clean flush-and-close
46-
semantics.
47-
48-
- **``NestedColumn`` public class**: the dotted-column accessor is now a proper
49-
public class with aggregate metadata (``nbytes``, ``cbytes``, ``cratio``) and
50-
a structured ``.info`` report.
51-
52-
- **Python 3.10 dropped**: Python 3.11 is now the minimum supported version.
35+
import blosc2
36+
import dataclasses
37+
import numpy as np
5338

54-
A small example showing the new SUMMARY index benefit::
39+
@dataclasses.dataclass
40+
class Row:
41+
price: float = blosc2.field(blosc2.float64())
42+
qty: int = blosc2.field(blosc2.int64())
5543

56-
import blosc2
44+
@blosc2.dsl_kernel
45+
def revenue(price, qty):
46+
return price * qty
5747

58-
# Create a table and let SUMMARY indexes be built automatically on close
59-
t = blosc2.CTable(Row, urlpath="my_table.b2d", mode="w")
60-
t.extend(data)
61-
t.close() # SUMMARY indexes built here
48+
t = blosc2.CTable(Row, new_data=[(1.5, 10), (2.0, 5), (3.0, 3)])
49+
t.add_computed_column("revenue", revenue, inputs=["price", "qty"])
50+
print(t["revenue"][:]) # array([15., 10., 9.])
6251

63-
# Re-open and run a selective WHERE query — block skipping kicks in
64-
t = blosc2.open("my_table.b2d")
65-
result = t.where(t.value > 0.99)
66-
print(result[:])
52+
# Column assignment with a blosc2.NDArray — written chunk-by-chunk
53+
new_prices = blosc2.array([1.0, 2.5, 4.0])
54+
t["price"] = new_prices
6755

6856
Install it with::
6957

RELEASE_NOTES.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,89 @@
22

33
## Changes from 4.4.1 to 4.4.2
44

5-
XXX version-specific blurb XXX
5+
This is a feature and maintenance release that promotes DSL kernels to
6+
first-class CTable computed columns, adds a new `CTable.__setitem__`
7+
assignment idiom, optimises bulk NDArray writes, and fixes several
8+
correctness issues.
9+
10+
### DSL kernels as first-class CTable columns
11+
12+
- **`add_computed_column()` accepts DSL kernels**: `@blosc2.dsl_kernel`-decorated
13+
functions can now back virtual computed columns directly, in addition to
14+
the existing string-expression form. The column survives save/open
15+
round-trips via persisted `dsl_source`.
16+
- **`add_generated_column()` accepts DSL kernels**: stored generated columns
17+
(written during `append`/`extend` and on `refresh_generated_column()`)
18+
now support DSL kernels as their transformer.
19+
- **`CTable.where()` accepts UDF/DSL kernels**: filter predicates are no
20+
longer limited to expression strings — any DSL kernel can be passed directly.
21+
- **`dtype` inference for DSL kernels**: when `dtype` is omitted,
22+
`lazyudf()` infers the output dtype via NumPy type promotion of the input
23+
column dtypes. Pass `dtype` explicitly for type-changing kernels
24+
(comparisons, casts).
25+
- **`kernel_from_source()` utility**: new `dsl_kernel.kernel_from_source()`
26+
reconstructs a `DSLKernel` from its stored source text, shared by the
27+
CTable DSL-column loaders and the persisted `LazyUDF` decoder.
28+
- **Security note**: `.b2d` files from untrusted sources that contain DSL
29+
computed columns execute stored Python source on open. A warning is now
30+
included in the documentation.
31+
32+
### New `CTable.__setitem__` column-assignment API
33+
34+
- **`t["col"] = arr`**: new shorthand equivalent to `t["col"][:] = arr`.
35+
Accepts any array-like including `blosc2.NDArray`. Raises `KeyError` for
36+
unknown columns and `ValueError` for views or read-only tables.
37+
38+
### Chunked NDArray writes in `extend()` and `Column.__setitem__`
39+
40+
- **`extend({"col": ndarray})` decompresses chunk-by-chunk**: when a
41+
`blosc2.NDArray` is passed as a column value to `extend()`, it is now
42+
written in chunks instead of being fully decompressed upfront. Pass
43+
`validate=False` to avoid a transient full decompression during constraint
44+
checking.
45+
- **`col[:] = blosc2_ndarray` fast path**: a new no-holes fast path in
46+
`Column.__setitem__` skips the O(n) validity-mask gather and writes the
47+
NDArray one chunk at a time using contiguous slice writes. Works for both
48+
scalar and fixed-shape ndarray columns. Falls back to a chunked fancy-index
49+
path when deleted rows are present.
50+
51+
### `BLOSC_ME_JIT` environment variable override
52+
53+
- **Full CLI override**: `BLOSC_ME_JIT` now takes unconditional priority over
54+
both the `jit=` and `jit_backend=` keyword arguments, making it easy to
55+
switch JIT backends from the command line without modifying code.
56+
57+
### Correctness fixes
58+
59+
- **View corruption in `Column.__setitem__`**: a `None == None` guard
60+
evaluation on view-backed columns could fire the NDArray fast path,
61+
bypassing physical-position remapping and silently corrupting rows. Fixed
62+
by explicitly checking `base is None` before activating the fast path.
63+
- **`CTable.__setitem__` view guard**: the new `t["col"] = arr` API now
64+
raises `ValueError` on views, matching the contract of all other mutating
65+
CTable methods.
66+
- **Fast path enabled for disk-opened tables**: the fast path previously
67+
remained dormant for tables opened from disk because `_last_pos` starts as
68+
`None`. The guard now calls `_resolve_last_pos()` to lazily initialise it.
69+
- **DSL column `jit_backend` preserved in `_empty_copy`**: the `jit_backend`
70+
setting was silently dropped during internal table copies; it is now
71+
retained.
72+
- **`lazyexpr` Column unwrapping**: `convert_inputs()` now automatically
73+
unwraps `CTable.Column` objects to their backing NDArray so that shape and
74+
identity checks work correctly.
75+
76+
### Documentation and examples
77+
78+
- **Parquet-to-blosc2 walkthrough**: new step-by-step tutorial added to the
79+
getting-started section. Thanks to @SyedIshmumAhnaf.
80+
- **CTable performance tips**: new section in the overview covering when to
81+
prefer computed vs. generated columns, chunk sizing, and query optimisation.
82+
- **Simplified docstring examples**: examples throughout `ndarray.py` and
83+
`ctable.py` now use `blosc2.array()`, `blosc2.arange()`, and
84+
`blosc2.linspace()` directly instead of two-step numpy-then-`asarray`
85+
patterns.
86+
- **`udf-computed-col.py` example**: new end-to-end example demonstrating DSL
87+
kernel computed and generated columns.
688

789
## Changes from 4.3.3 to 4.4.1
890

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ dependencies = [
4040
"requests",
4141
"threadpoolctl; platform_machine != 'wasm32'",
4242
]
43-
version = "4.4.2.dev0"
43+
version = "4.4.2"
4444
[project.entry-points."array_api"]
4545
blosc2 = "blosc2"
4646

src/blosc2/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "4.4.2.dev0"
1+
__version__ = "4.4.2"
22
__array_api_version__ = "2024.12"

0 commit comments

Comments
 (0)