fix: JsonObject array/scalar variants now implement standard dict protocol by waiho-gumloop · Pull Request #16496 · googleapis/google-cloud-python
Description
JsonObject subclasses dict but when wrapping arrays or scalars, __init__ returns early without calling super().__init__(). This leaves the dict parent empty, causing len(), bool(), iter(), indexing, json.dumps(), and in to silently return wrong results -- while isinstance(obj, dict) returns True.
This has been present since the array support was added in Aug 2022 (googleapis/python-spanner#782).
What this PR does
Adds __len__, __bool__, __iter__, __getitem__, __contains__, and __eq__ overrides that delegate to the internal _array_value/_simple_value for non-dict variants. Dict variant behavior is unchanged (delegates to super()).
Before (broken)
val = JsonObject([{"id": "m1", "content": "hello"}]) isinstance(val, dict) # True len(val) # 0 <-- wrong bool(val) # False <-- wrong list(val) # [] <-- wrong json.dumps(val) # "{}" <-- wrong
After (fixed)
val = JsonObject([{"id": "m1", "content": "hello"}]) isinstance(val, dict) # True len(val) # 1 <-- correct bool(val) # True <-- correct list(val) # [{"id": "m1", "content": "hello"}] <-- correct val[0] # {"id": "m1", "content": "hello"} <-- correct
Tests
Added Test_JsonObject_dict_protocol test class covering len, bool, iter, getitem, contains, and eq for all four variants (array, dict, scalar, null). All tests pass.
Fixes #15870