Skip to content

Commit cb3419a

Browse files
committed
fix errors in jsonToArray function
1 parent c6d77f8 commit cb3419a

File tree

2 files changed

+55
-55
lines changed

2 files changed

+55
-55
lines changed

src/h5json/array_util.py

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,6 @@ def jsonToArray(data_shape, data_dtype, data_json):
107107
"""
108108
Return numpy array from the given json array.
109109
"""
110-
# print(f"jsonToArray: data_shape: {data_shape}, data_dtype: {data_dtype} data_json: {data_json}")
111-
def fillVlenArray(rank, data, arr, index):
112-
# print(f"fillVlenArray rank: {rank} data: {data} arr: {arr} index: {index}")
113-
if arr.shape == ():
114-
arr[()] = data
115-
else:
116-
for i in range(len(data)):
117-
if rank > 1:
118-
index = fillVlenArray(rank - 1, data[i], arr, index)
119-
else:
120-
arr[index] = data[i]
121-
index += 1
122-
return index
123110

124111
if data_json is None:
125112
return np.array([]).astype(data_dtype)
@@ -131,42 +118,30 @@ def fillVlenArray(rank, data, arr, index):
131118
# need some special conversion for compound types --
132119
# each element must be a tuple, but the JSON decoder
133120
# gives us a list instead.
134-
if len(data_dtype) > 1 and not isinstance(data_json, (list, tuple)):
121+
if len(data_dtype) > 0 and not isinstance(data_json, (list, tuple)):
135122
raise TypeError("expected list data for compound data type")
136123
npoints = getNumElements(data_shape)
137124
np_shape_rank = len(data_shape)
138125

139126
if type(data_json) in (list, tuple):
140-
converted_data = []
141-
if np_shape_rank > 0 and npoints == 1 and len(data_json) == len(data_dtype):
142-
converted_data.append(toTuple(0, data_json))
143-
else:
144-
converted_data = toTuple(np_shape_rank, data_json)
145-
data_json = converted_data
127+
data_json = toTuple(np_shape_rank, data_json)
146128

147-
if isVlen(data_dtype):
148-
if np_shape_rank == 0 and npoints == 1:
149-
arr_shape = ()
150-
else:
151-
arr_shape = (npoints,)
152-
arr = np.zeros(arr_shape, dtype=data_dtype)
153-
fillVlenArray(np_shape_rank, data_json, arr, 0)
154-
else:
155-
try:
156-
arr = np.array(data_json, dtype=data_dtype)
157-
except UnicodeEncodeError:
158-
# Unable to encode data, encode as utf8 with surrogate escaping
159-
data_json = toTuple(np_shape_rank, data_json, encoding="utf8")
160-
arr = np.array(data_json, dtype=data_dtype)
129+
arr = np.zeros(data_shape, dtype=data_dtype)
130+
131+
try:
132+
# arr = np.array(data_json, dtype=data_dtype)
133+
arr[...] = data_json
134+
except UnicodeEncodeError:
135+
# Unable to encode data, encode as utf8 with surrogate escaping
136+
data_json = toTuple(np_shape_rank, data_json, encoding="utf8")
137+
arr[...] = data_json
161138
# raise an exception of the array shape doesn't match the selection shape
162139
# allow if the array is a scalar and the selection shape is one element,
163140
# numpy is ok with this
164141
if arr.size != npoints:
165142
msg = "Input data doesn't match selection number of elements"
166143
msg += f" Expected {npoints}, but received: {arr.size}"
167144
raise ValueError(msg)
168-
if arr.shape != data_shape:
169-
arr = arr.reshape(data_shape) # reshape to match selection
170145

171146
return arr
172147

test/unit/array_util_test.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ def testToTuple(self):
8282
out = toTuple(1, data3d) # treat input a 1d array of compound type of compound types
8383
self.assertEqual([((0, 0.0), (1, 0.1)), ((2, 0.2), (3, 0.3))], out)
8484

85+
def testToTupleStrData(self):
86+
data = "a string!"
87+
out = toTuple(0, data)
88+
self.assertEqual(data, out)
89+
90+
data = ["a string!"]
91+
out = toTuple(1, data)
92+
self.assertEqual(data, out)
93+
94+
data = ["a string2"]
95+
out = toTuple(1, data)
96+
self.assertEqual(data, out)
97+
98+
data = [["partA", "partB", "partC"],]
99+
out = toTuple(1, data)
100+
self.assertEqual([("partA", "partB", "partC"), ], out)
101+
102+
data = [[[4, 8, 12], "four"], [[5, 10, 15], "five"]]
103+
out = toTuple(1, data)
104+
self.assertEqual([((4, 8, 12), 'four'), ((5, 10, 15), 'five')], out)
105+
85106
def testGetNumElements(self):
86107
shape = (4,)
87108
nelements = getNumElements(shape)
@@ -98,7 +119,6 @@ def testGetNumElements(self):
98119
def testJsonToArray(self):
99120

100121
# simple integer
101-
102122
dt = np.dtype("i4")
103123
shape = [4, ]
104124
data = [0, 2, 4, 6]
@@ -151,6 +171,14 @@ def testJsonToArray(self):
151171
val = out[0]
152172
self.assertEqual(val, data)
153173

174+
# VLEN multi element
175+
shape = [5, ]
176+
data = ["parting", "is", "such", "sweet", "sorrow"]
177+
out = jsonToArray(shape, dt, data)
178+
self.assertTrue(isinstance(out, np.ndarray))
179+
self.assertEqual(out.shape, (5, ))
180+
self.assertEqual(out[4], 'sorrow')
181+
154182
# VLEN ascii
155183
dt = special_dtype(vlen=bytes)
156184
data = [b"one", b"two", b"three", b"four", b"five"]
@@ -167,22 +195,6 @@ def testJsonToArray(self):
167195
self.assertEqual(out[2], b"three")
168196
self.assertEqual(out[3], b"four")
169197

170-
# VLEN str
171-
dt = special_dtype(vlen=str)
172-
data = [
173-
[b"part 1 - section A", b"part 1 - section B"],
174-
[b"part 2 - section A", b"part 2 - section B"],
175-
]
176-
shape = [2,]
177-
out = jsonToArray(shape, dt, data)
178-
self.assertTrue(isinstance(out, np.ndarray))
179-
self.assertTrue("vlen" in out.dtype.metadata)
180-
self.assertEqual(out.dtype.metadata["vlen"], str)
181-
self.assertEqual(out.dtype.kind, "O")
182-
self.assertEqual(out.shape, (2,))
183-
self.assertEqual(out[0], tuple(data[0]))
184-
self.assertEqual(out[1], tuple(data[1]))
185-
186198
# VLEN unicode
187199
dt = special_dtype(vlen=bytes)
188200
data = ["one", "two", "three", "four", "five"]
@@ -207,6 +219,12 @@ def testJsonToArray(self):
207219
self.assertTrue(isinstance(out, np.ndarray))
208220
self.assertEqual(out[()], data)
209221

222+
data = ["I'm an UTF-8 null terminated string",]
223+
shape = [1,]
224+
out = jsonToArray(shape, dt, data)
225+
self.assertTrue(isinstance(out, np.ndarray))
226+
self.assertEqual(out[0], data[0])
227+
210228
dt = np.dtype("S12")
211229
data = "eight: \u516b"
212230
out = jsonToArray(shape, dt, data)
@@ -223,9 +241,16 @@ def testJsonToArray(self):
223241
dt = np.dtype("S12")
224242
data = "eight: \u516b"
225243
out = jsonToArray(shape, dt, data)
244+
self.assertTrue(isinstance(out, np.ndarray))
226245
self.assertEqual(out[0], b'eight: \xe5\x85\xab')
227246

228247
# VLEN data
248+
shape = []
249+
dt = special_dtype(vlen=np.dtype("S10"))
250+
data = ["foo", "bar"]
251+
out = jsonToArray(shape, dt, data)
252+
self.assertTrue(isinstance(out, np.ndarray))
253+
229254
dt = special_dtype(vlen=np.dtype("int32"))
230255
shape = [4, ]
231256
data = [
@@ -321,7 +346,7 @@ def testJsonToArray(self):
321346
e1 = out[1].tolist()
322347
self.assertEqual(e1, (5, b"five"))
323348

324-
data = [6, "six"]
349+
data = [[6, "six"],]
325350
shape = [1,]
326351
out = jsonToArray(shape, dt, data)
327352
self.assertTrue(isinstance(out, np.ndarray))
@@ -352,7 +377,7 @@ def testJsonToArray(self):
352377
self.assertEqual(e0, (4, "four"))
353378

354379
shape = [1, ]
355-
data = [6, "six"]
380+
data = [[6, "six"],]
356381
out = jsonToArray(shape, dt, data)
357382
self.assertTrue(isinstance(out, np.ndarray))
358383
self.assertEqual(out.shape, (1,))

0 commit comments

Comments
 (0)