Skip to content

JsonValue

Type: warmhub.JsonValue

JsonValue = 'str | int | float | bool | Sequence[JsonValue] | Mapping[str, JsonValue] | None'

Anything a JSON document can hold, defined recursively.

This is the annotation for payloads the client carries but does not model: data, metadata, extra, raw. It replaces a bare Any, which said “this is anything” when the truth is “this is JSON”. The difference is not cosmetic: Any silently accepts item.data["temp"].strftime(...), and JsonValue makes the caller narrow first.

The container arms are Sequence/Mapping and NOT list/dict, which is worth stating because the tighter spelling looks more honest and is not. This client’s own sequence returns are tuple (see deep_freeze), so list would be a fresh lie in the direction that actually matters here — the read direction. Sequence and Mapping are also covariant, so a caller’s dict[str, list[str]] payload is assignable; the invariant list[JsonValue] would reject it. The residue is real and accepted: a custom Sequence type-checks as JsonValue and would fail in json.dumps. Nothing in this package constructs one, and no write path is annotated with this alias.

Recursive aliases need a string form on the 3.10 floor. mypy (1.14 and 2.3) and pyright 1.1.411 all resolve it; docs/dev/architecture/python-sdk/ typing_fixture.py is the proof.