@@ -1369,25 +1369,29 @@ def __setitem__(self, args, val):
1369
1369
# Generally we try to avoid converting the arrays on the Python
1370
1370
# side. However, for compound literals this is unavoidable.
1371
1371
# For h5pyd, do extra check and convert type on client side for efficiency
1372
- vlen = check_dtype (vlen = self .dtype )
1373
-
1374
- if not isinstance (val , numpy .ndarray ) and vlen is not None and vlen not in (bytes , str ):
1372
+ vlen_base_class = check_dtype (vlen = self .dtype )
1373
+ if vlen_base_class is not None and vlen_base_class not in (bytes , str ):
1375
1374
try :
1376
- val = numpy .asarray (val , dtype = vlen )
1375
+ # Attempt to directly convert the input array of vlen data to its base class
1376
+ val = numpy .asarray (val , dtype = vlen_base_class )
1377
1377
1378
1378
except ValueError as ve :
1379
+ # Failed to convert input array to vlen base class directly, instead create a new array where
1380
+ # each element is an array of the Dataset's dtype
1379
1381
self .log .debug (f"asarray ValueError: { ve } " )
1380
1382
try :
1381
- val = numpy . array (
1382
- [ numpy .array ( x , dtype = self .dtype ) for x in val ],
1383
- dtype = self .dtype ,
1384
- )
1383
+ # Force output shape
1384
+ tmp = numpy .empty ( shape = val . shape , dtype = self .dtype )
1385
+ tmp [:] = [ numpy . array ( x , dtype = self .dtype ) for x in val ]
1386
+ val = tmp
1385
1387
except ValueError as e :
1386
1388
msg = f"ValueError converting value element by element: { e } "
1387
1389
self .log .debug (msg )
1388
1390
1389
- if vlen == val .dtype :
1391
+ if vlen_base_class == val .dtype :
1390
1392
if val .ndim > 1 :
1393
+ # Reshape array to 2D, where first dim = product of all dims except last, and second dim = last dim
1394
+ # Then flatten it to 1D
1391
1395
tmp = numpy .empty (shape = val .shape [:- 1 ], dtype = self .dtype )
1392
1396
tmp .ravel ()[:] = [
1393
1397
i
@@ -1434,6 +1438,7 @@ def __setitem__(self, args, val):
1434
1438
else :
1435
1439
dtype = self .dtype
1436
1440
cast_compound = False
1441
+
1437
1442
val = numpy .asarray (val , dtype = dtype , order = "C" )
1438
1443
if cast_compound :
1439
1444
val = val .astype (numpy .dtype ([(names [0 ], dtype )]))
@@ -1520,7 +1525,7 @@ def __setitem__(self, args, val):
1520
1525
if self .id .uuid .startswith ("d-" ):
1521
1526
# server is HSDS, use binary data, use param values for selection
1522
1527
format = "binary"
1523
- body = arrayToBytes (val , vlen = vlen )
1528
+ body = arrayToBytes (val , vlen = vlen_base_class )
1524
1529
self .log .debug (f"writing binary data, { len (body )} " )
1525
1530
else :
1526
1531
# h5serv, base64 encode, body json for selection
0 commit comments