From 822fe7664a15ce07e0cc1bfce1df86fbe1b81e24 Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:05:35 -0500 Subject: [PATCH] Fix jsonToArray error on empty data read (#237) * Fix jsonToArray error on empty data read This lets clients read from an empty attribute without causing an internal server error. * Add test for empty jsonToArray --- hsds/util/arrayUtil.py | 37 +++++++++++++++++++---------------- tests/unit/array_util_test.py | 14 +++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/hsds/util/arrayUtil.py b/hsds/util/arrayUtil.py index e040df48..0b8fd4bd 100644 --- a/hsds/util/arrayUtil.py +++ b/hsds/util/arrayUtil.py @@ -174,24 +174,27 @@ def fillVlenArray(rank, data, arr, index): data_json, ] # listify - if isVlen(data_dtype): - arr = np.zeros((npoints,), dtype=data_dtype) - fillVlenArray(np_shape_rank, data_json, arr, 0) + if not (None in data_json): + if isVlen(data_dtype): + arr = np.zeros((npoints,), dtype=data_dtype) + fillVlenArray(np_shape_rank, data_json, arr, 0) + else: + try: + arr = np.array(data_json, dtype=data_dtype) + except UnicodeEncodeError as ude: + msg = "Unable to encode data" + raise ValueError(msg) from ude + # raise an exception of the array shape doesn't match the selection shape + # allow if the array is a scalar and the selection shape is one element, + # numpy is ok with this + if arr.size != npoints: + msg = "Input data doesn't match selection number of elements" + msg += f" Expected {npoints}, but received: {arr.size}" + raise ValueError(msg) + if arr.shape != data_shape: + arr = arr.reshape(data_shape) # reshape to match selection else: - try: - arr = np.array(data_json, dtype=data_dtype) - except UnicodeEncodeError as ude: - msg = "Unable to encode data" - raise ValueError(msg) from ude - # raise an exception of the array shape doesn't match the selection shape - # allow if the array is a scalar and the selection shape is one element, - # numpy is ok with this - if arr.size != npoints: - msg = "Input data doesn't match selection number of elements" - msg += f" Expected {npoints}, but received: {arr.size}" - raise ValueError(msg) - if arr.shape != data_shape: - arr = arr.reshape(data_shape) # reshape to match selection + arr = np.array([]).astype(data_dtype) return arr diff --git a/tests/unit/array_util_test.py b/tests/unit/array_util_test.py index 0e36c9de..56bc4351 100644 --- a/tests/unit/array_util_test.py +++ b/tests/unit/array_util_test.py @@ -673,6 +673,20 @@ def testIndexIterator(self): cnt += 1 self.assertEqual(cnt, 20) + def testJsonToArrayOnNoneArray(self): + data_dtype = np.dtype("i4") + data_shape = [0, ] + data_json = [None] + arr = None + + try: + arr = jsonToArray(data_shape, data_dtype, data_json) + except Exception as e: + print(f"Exception while testing jsonToArray on array with None elements: {e}") + + self.assertTrue(len(arr) == 0) + self.assertTrue(arr.dtype == data_dtype) + if __name__ == "__main__": # setup test files