zarr_indexing.messages
zarr_indexing.messages ¶
The ndsel message layer — pure JSON in, canonical JSON out.
This module implements the ndsel draft wire
format: a JSON-serializable representation of NumPy-style n-dimensional
selections that adapts TensorStore's IndexTransform model. It is a pure
JSON→JSON layer depending only on the standard library. It validates and
desugars messages, removing redundant fields on constant maps. It limits input
rank to 32 and checks affine references against that rank. Finite bounds and
in-memory array construction are enforced by the engine lowering layer.
Two entry points:
parse_ndsel(obj)— structurally validate an ndsel message of any of the five kinds (point/box/slice/points/transform), returning it unchanged. RaisesNdselError(carrying a spec reason code) on any defect.normalize_ndsel(obj)— desugar and canonicalize a message to the single deterministic canonical transform body of the spec (section 4.3): a bareIndexTransformJSON body, without thekinddiscriminator.normalizeis idempotent when its output is re-tagged withkind: "transform".
The canonical body uses TensorStore's IndexTransform field vocabulary.
Normalization alone does not guarantee TensorStore acceptance: index-array
content is deferred, and TensorStore has additional coordinate and label limits.
Value rules for validated fields (excluding the verbatim index_array payload
and discarded constant-map fields): integers are 64-bit signed values; JSON
booleans are not integers (Python's isinstance(True, int) is guarded
against explicitly); the "-inf"/"+inf" sentinels are legal only in bound
positions; an implicit bound is the one-element [n]-bracket form, and its
implicit/explicit flag is preserved through normalization.
REASON_CODES
module-attribute
¶
REASON_CODES = frozenset(
{
"invalid_json",
"unknown_kind",
"unknown_field",
"multiple_upper_bounds",
"bounds_out_of_order",
"output_map_conflict",
"rank_mismatch",
"step_zero",
"negative_step_unsupported",
}
)
NdselError ¶
Bases: ValueError
An ndsel message failed validation.
Carries the spec reason code (one of REASON_CODES) so callers and the
conformance harness can assert on it directly, plus a human-readable
detail.
Examples:
>>> try:
... normalize_ndsel({"kind": "bogus"})
... except NdselError as error:
... (error.reason, str(error))
('unknown_kind', "unknown_kind: unknown kind 'bogus'")
Source code in src/zarr_indexing/messages.py
__init__ ¶
Store reason and detail and compose the message as "reason: detail".
reason is a spec reason code (one of REASON_CODES); detail is
optional human-readable context, and when empty the message is the
bare reason.
Source code in src/zarr_indexing/messages.py
normalize_ndsel ¶
Desugar and canonicalize an ndsel message to its canonical transform body.
Accepts any of the five message kinds and returns the bare canonical
IndexTransform body of spec section 4.3 — no kind field. Raises
NdselError (carrying a reason code) for any invalid input.
Examples:
>>> body = normalize_ndsel({"kind": "box", "shape": [2, 3]})
>>> (body["input_rank"], body["input_inclusive_min"], body["input_exclusive_max"])
(2, [0, 0], [2, 3])
>>> body["output"][0]
{'offset': 0, 'stride': 1, 'input_dimension': 0}
Source code in src/zarr_indexing/messages.py
parse_ndsel ¶
Structurally validate an ndsel message, returning it unchanged.
Runs the same validation and desugaring as normalize_ndsel, discards
the canonical body, and returns the original object. Useful for validating
a message you intend to keep in its compact shorthand form. Index-array
payload validation remains the engine's responsibility.
Examples:
>>> message = {"kind": "point", "coords": [3, 4]}
>>> parse_ndsel(message) is message
True
>>> normalize_ndsel(message)["output"]
[{'offset': 3}, {'offset': 4}]