jsonutil
JSON helpers backed by orjson; falls back to stdlib json when required.
Drop-in replacement for the stdlib json module used across every
Stargazer service – callers do import jsonutil as json and then use the
familiar dumps(), loads(), dump(), and load() names. The
fast orjson path is taken whenever the requested options fall within its
capabilities; otherwise the call transparently routes to the stdlib serializer
(decided by _needs_stdlib_dumps() and _option_bits()) so behaviour
stays compatible. loads likewise retries on the stdlib decoder for inputs
orjson rejects (e.g. lone surrogates).
These functions perform no I/O of their own beyond what the caller’s file handle
does; they encode and decode in memory and are exercised pervasively for Redis
payloads, tool arguments, cached blobs, and LLM/JSON responses throughout the
repo. JSONDecodeError is aliased to the stdlib exception so that a single
except json.JSONDecodeError catches failures from either backend.
- jsonutil.dumps(obj, *, skipkeys=False, ensure_ascii=False, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)[source]
Serialize obj to a JSON string (UTF-8 text, like
ensure_ascii=False).The codebase’s drop-in for
json.dumps(imported asjson). It first asks_needs_stdlib_dumps()whether the requested formatting options exceed orjson’s feature set; when they do it delegates to_stdlib_json.dumpswith every argument forwarded unchanged, and otherwise takes the fastorjson.dumpspath with options translated by_option_bits(). As a final safety net, aTypeErrorfrom orjson (notably lone surrogate code points in string values, which orjson refuses but stdlib accepts) is caught and retried on the stdlib serializer withensure_ascii=False. Unlike the stdlib default,ensure_asciidefaults toFalsehere so non-ASCII text is emitted as UTF-8 rather than escaped.Pure in-memory serialization with no I/O. Called directly by
dump()(which writes the result to a file) and, via theimport jsonutil as jsonalias, by essentially every module that serializes data for Redis, tool payloads, prompt overlays, or persisted state.- Parameters:
obj (
Any) – The Python object to serialize.skipkeys (
bool) – Skip non-basic dict keys (forces the stdlib path).ensure_ascii (
bool) – Escape non-ASCII whenTrue(forces the stdlib path); defaults toFalseso output is UTF-8.check_circular (
bool) – Enable circular-reference detection; disabling it forces the stdlib path.allow_nan (
bool) – PermitNaN/Infinityoutput;Falseforces the stdlib path.cls (
type|None) – Optional customJSONEncodersubclass; any value forces the stdlib path.indent (
int|str|None) – Indentation spec. Integer2or4use orjson’s native indent; string indents and other integers force the stdlib path;Noneproduces compact output.separators (
tuple[str,str] |None) – Item/key separator pair; anything other thanNoneor the compact(",", ":")forces the stdlib path.default (
Optional[Callable[...,Any]]) – Fallback callable invoked for otherwise-unserializable values.sort_keys (
bool) – Emit object keys in sorted order.
- Returns:
The serialized JSON text.
- Return type:
- Raises:
TypeError – Propagated from the stdlib serializer for objects that remain unserializable (e.g. when no suitable
defaultis supplied).
- jsonutil.loads(s)[source]
Deserialize a JSON document from text or bytes into a Python object.
Parses with the fast
orjson.loadsfirst and, if that raises aJSONDecodeError(notably for inputs containing lone surrogates that orjson rejects), retries with the more permissive stdlibjson.loads, decoding bytes witherrors="surrogatepass"so such characters survive.This is the drop-in replacement for
json.loadsused throughout the codebase, which imports this module asjson(e.g.import jsonutil as json).load()calls it after reading a file’s contents, and many callers across services use it to decode Redis payloads, tool arguments, cached blobs, and LLM/JSON responses. It performs no I/O of its own.- Parameters:
s (
str|bytes|bytearray|memoryview) – The JSON document asstr,bytes,bytearray, ormemoryview(amemoryviewis materialized tobytesonly on the stdlib fallback).- Returns:
The decoded Python object (dict, list, str, int, float, bool, or
None).- Return type:
- Raises:
JSONDecodeError – If the input is not valid JSON for either backend.
- jsonutil.load(fp)[source]
Read a file-like object and deserialize its full contents as JSON.
Reads the entire stream via
fp.read()and delegates parsing toloads(), inheriting its orjson-first/stdlib-fallback behaviour. This is the drop-injson.loadfor the codebase (imported asjson).It calls
loads()and triggers I/O throughfp.read(). Callers open a file and pass the handle – e.g.threadweave.pyloads persisted state, and various parsers/classifier index loaders (scripts/...,classifiers/...) read JSON fixtures and index files this way.
- jsonutil.dump(obj, fp, *, skipkeys=False, ensure_ascii=False, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)[source]
Serialize obj to JSON and write the result to a file-like object.
Produces the JSON text via
dumps()(forwarding every stdlib-style formatting option unchanged) and writes it in a singlefp.writecall. Becausedumps()decides between the orjson fast path and the stdlib fallback, the same option compatibility rules apply here. This is the drop-injson.dumpfor the codebase (imported asjson).It calls
dumps()to build the payload and performs I/O throughfp.write. Callers open a file for writing and pass the handle – e.g.threadweave.pypersists state withindent=2,memories_portexport scripts dump memory exports, and classifier/tool index builders write index files this way.- Parameters:
obj (
Any) – The Python object to serialize.fp (
IO[str]) – An open, writable text file-like object to receive the JSON text.skipkeys (
bool) – Forwarded todumps(); skip non-basic dict keys.ensure_ascii (
bool) – Forwarded todumps(); escape non-ASCII whenTrue.check_circular (
bool) – Forwarded todumps(); enable circular-reference checking.allow_nan (
bool) – Forwarded todumps(); permit NaN/Infinity output.cls (
type|None) – Forwarded todumps(); optional customJSONEncoderclass.indent (
int|str|None) – Forwarded todumps(); indentation spec for pretty output.separators (
tuple[str,str] |None) – Forwarded todumps(); item/key separator pair.default (
Optional[Callable[...,Any]]) – Forwarded todumps(); fallback serializer for otherwise-unserializable values.sort_keys (
bool) – Forwarded todumps(); emit object keys in sorted order.
- Raises:
TypeError – Propagated from
dumps()for unserializable objects on the stdlib path.- Return type: