@@ -259,6 +259,33 @@ def dtype_to_descr(dtype):
259
259
else :
260
260
return dtype .str
261
261
262
+ def descr_to_dtype (descr ):
263
+ if isinstance (descr , str ):
264
+ # descr was produced by dtype.str, so this always works
265
+ return numpy .dtype (descr )
266
+
267
+ fields = []
268
+ offset = 0
269
+ for field in descr :
270
+ if len (field ) == 2 :
271
+ name , descr_str = field
272
+ dt = descr_to_dtype (descr_str )
273
+ else :
274
+ name , descr_str , shape = field
275
+ dt = numpy .dtype ((descr_to_dtype (descr_str ), shape ))
276
+
277
+ # ignore padding bytes, which will be void bytes with '' as name
278
+ # (once blank fieldnames are deprecated, only "if name == ''" needed)
279
+ is_pad = (name == '' and dt .type is numpy .void and dt .names is None )
280
+ if not is_pad :
281
+ fields .append ((name , dt , offset ))
282
+
283
+ offset += dt .itemsize
284
+
285
+ names , formats , offsets = zip (* fields )
286
+ return numpy .dtype ({'names' : names , 'formats' : formats ,
287
+ 'offsets' : offsets , 'itemsize' : offset })
288
+
262
289
def header_data_from_array_1_0 (array ):
263
290
""" Get the dictionary of header metadata from a numpy.ndarray.
264
291
@@ -523,7 +550,8 @@ def _read_array_header(fp, version):
523
550
msg = "fortran_order is not a valid bool: %r"
524
551
raise ValueError (msg % (d ['fortran_order' ],))
525
552
try :
526
- dtype = numpy .dtype (d ['descr' ])
553
+ descr = descr_to_dtype (d ['descr' ])
554
+ dtype = numpy .dtype (descr )
527
555
except TypeError as e :
528
556
msg = "descr is not a valid dtype descriptor: %r"
529
557
raise ValueError (msg % (d ['descr' ],))
0 commit comments