Skip to content

Commit 9339283

Browse files
fix(spanner): implement dict protocol and nested unwrapping for JsonObject
1 parent d004f70 commit 9339283

3 files changed

Lines changed: 28 additions & 16 deletions

File tree

packages/google-cloud-spanner/google/cloud/spanner_v1/data_types.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ def __init__(self, *args, **kwargs):
5454
elif self._is_scalar_value:
5555
self._simple_value = args[0]._simple_value
5656

57-
if not self._is_null:
57+
if self._is_null:
58+
super().__init__({"__json_null__": True})
59+
else:
5860
super().__init__(*args, **kwargs)
5961

6062
def __len__(self):
@@ -72,7 +74,7 @@ def __bool__(self):
7274
if self._is_array:
7375
return bool(self._array_value)
7476
if self._is_scalar_value:
75-
return True
77+
return bool(self._simple_value)
7678
return super().__len__() > 0
7779

7880
def __iter__(self):
@@ -106,30 +108,27 @@ def __contains__(self, item):
106108
def __eq__(self, other):
107109
if isinstance(other, JsonObject):
108110
if self._is_array:
109-
return (
110-
getattr(other, "_is_array", False)
111-
and self._array_value == other._array_value
112-
)
111+
return other._is_array and self._array_value == other._array_value
113112
if self._is_scalar_value:
114113
return (
115-
getattr(other, "_is_scalar_value", False)
116-
and self._simple_value == other._simple_value
114+
other._is_scalar_value and self._simple_value == other._simple_value
117115
)
118116
if self._is_null:
119-
return getattr(other, "_is_null", False)
117+
return other._is_null
120118
return not (
121-
getattr(other, "_is_array", False)
122-
or getattr(other, "_is_scalar_value", False)
123-
or getattr(other, "_is_null", False)
119+
other._is_array or other._is_scalar_value or other._is_null
124120
) and super().__eq__(other)
125121
if self._is_array:
126122
return self._array_value == other
127123
if self._is_scalar_value:
128124
return self._simple_value == other
129125
if self._is_null:
130-
return other is None or (isinstance(other, dict) and len(other) == 0)
126+
return other is None
131127
return super().__eq__(other)
132128

129+
def __ne__(self, other):
130+
return not (self == other)
131+
133132
def __repr__(self):
134133
if self._is_array:
135134
return str(self._array_value)

packages/google-cloud-spanner/tests/unit/test__helpers.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ def test_w_json(self):
868868
from google.protobuf.struct_pb2 import Value
869869

870870
from google.cloud.spanner_v1 import Type, TypeCode
871+
from google.cloud.spanner_v1.data_types import JsonObject
871872

872873
VALUE = {"id": 27863, "Name": "Anamika"}
873874
str_repr = json.dumps(VALUE, sort_keys=True, separators=(",", ":"))
@@ -884,7 +885,9 @@ def test_w_json(self):
884885
field_type = Type(code=TypeCode.JSON)
885886
value_pb = Value(string_value=str_repr)
886887

887-
self.assertEqual(self._callFUT(value_pb, field_type, field_name), {})
888+
self.assertEqual(
889+
self._callFUT(value_pb, field_type, field_name), JsonObject(None)
890+
)
888891

889892
def test_w_unknown_type(self):
890893
from google.protobuf.struct_pb2 import Value

packages/google-cloud-spanner/tests/unit/test_datatypes.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,18 @@ def test_scalar_len(self):
132132
self.assertEqual(len(obj), 1)
133133

134134
def test_scalar_bool(self):
135-
obj = JsonObject(42)
136-
self.assertTrue(obj)
135+
self.assertTrue(JsonObject(42))
136+
self.assertFalse(JsonObject(False))
137+
self.assertFalse(JsonObject(0))
138+
self.assertFalse(JsonObject(0.0))
139+
self.assertFalse(JsonObject(""))
140+
141+
def test_null_eq(self):
142+
null_obj = JsonObject(None)
143+
self.assertEqual(null_obj, JsonObject(None))
144+
self.assertEqual(null_obj, None)
145+
self.assertNotEqual(null_obj, {})
146+
self.assertNotEqual(null_obj, JsonObject({}))
137147

138148
def test_scalar_not_iterable(self):
139149
obj = JsonObject(42)

0 commit comments

Comments
 (0)