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: it depends on nothing but the standard library, imposes no
engine (numpy/array) constraints, and never rounds, clamps, or drops
information. Engine constraints (finite bounds, in-memory IndexTransform
construction) live one layer up, in json.py.
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 is, field-for-field, a TensorStore IndexTransform (minus
kind), so a normalized transform loads directly into TensorStore once
kind is stripped.
Value rules enforced here: every integer is a 64-bit signed value; 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.
A lighter gate than normalize_ndsel: it confirms the message is a
well-formed ndsel message of a recognized kind (correct field membership,
JSON types, upper-bound exclusivity, domain ordering, step signs) and
raises NdselError otherwise, but does not desugar it. Useful for
validating a message you intend to keep in its compact shorthand form.
Examples:
>>> message = {"kind": "point", "coords": [3, 4]}
>>> parse_ndsel(message) is message
True
>>> normalize_ndsel(message)["output"]
[{'offset': 3}, {'offset': 4}]