Skip to content

Commit 89a45f3

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

2 files changed

Lines changed: 24 additions & 15 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_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)