Skip to content

Commit 7c8f802

Browse files
committed
return numpy boolean type for enums that match h5py boolean convention
1 parent 4bdd023 commit 7c8f802

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

h5json/hdf5dtype.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,14 @@ def createBaseDataType(typeItem):
488488
mapping = typeItem["mapping"]
489489
if len(mapping) == 0:
490490
raise KeyError("empty enum map")
491+
491492
dt = createBaseDataType(base_json)
492-
dtRet = special_dtype(enum=(dt, mapping))
493+
if dt.kind == 'i' and dt.name=='int8' and len(mapping) == 2 and 'TRUE' in mapping and 'FALSE' in mapping:
494+
# convert to numpy boolean type
495+
dtRet = np.dtype("bool")
496+
else:
497+
# not a boolean enum, use h5py special dtype
498+
dtRet = special_dtype(enum=(dt, mapping))
493499

494500
else:
495501
raise TypeError("Invalid type class")

test/unit/hdf5dtypeTest.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,20 @@ def testBaseEnumTypeItem(self):
9797
self.assertEqual(typeItem['mapping']['GREEN'], 1)
9898
self.assertEqual(typeSize, 1)
9999

100+
def testBaseBoolTypeItem(self):
101+
typeItem = hdf5dtype.getTypeItem(np.dtype('bool'))
102+
typeSize = hdf5dtype.getItemSize(typeItem)
103+
self.assertEqual(typeItem['class'], 'H5T_ENUM')
104+
baseItem = typeItem['base']
105+
self.assertEqual(baseItem['class'], 'H5T_INTEGER')
106+
self.assertEqual(baseItem['base'], 'H5T_STD_I8LE')
107+
self.assertTrue('mapping' in typeItem)
108+
mapping = typeItem['mapping']
109+
self.assertEqual(len(mapping), 2)
110+
self.assertEqual(mapping['FALSE'], 0)
111+
self.assertEqual(mapping['TRUE'], 1)
112+
self.assertEqual(typeSize, 1)
113+
100114
def testBaseArrayTypeItem(self):
101115
dt = np.dtype('(2,2)<int32')
102116
typeItem = hdf5dtype.getTypeItem(dt)
@@ -353,6 +367,54 @@ def testCreateOpaqueType(self):
353367
self.assertEqual(dt.kind, 'V')
354368
self.assertEqual(typeSize, 200)
355369

370+
def testCreateEnumType(self):
371+
typeItem = {
372+
"class": "H5T_ENUM",
373+
"base": {
374+
"base": "H5T_STD_I16LE",
375+
"class": "H5T_INTEGER"
376+
},
377+
"mapping": {
378+
"GAS": 2,
379+
"LIQUID": 1,
380+
"PLASMA": 3,
381+
"SOLID": 0
382+
}
383+
}
384+
385+
typeSize = hdf5dtype.getItemSize(typeItem)
386+
self.assertEqual(typeSize, 2)
387+
dt = hdf5dtype.createDataType(typeItem)
388+
self.assertEqual(dt.name, 'int16')
389+
self.assertEqual(dt.kind, 'i')
390+
mapping = check_dtype(enum=dt)
391+
self.assertTrue(isinstance(mapping, dict))
392+
self.assertEqual(mapping["SOLID"], 0)
393+
self.assertEqual(mapping["LIQUID"], 1)
394+
self.assertEqual(mapping["GAS"], 2)
395+
self.assertEqual(mapping["PLASMA"], 3)
396+
397+
def testCreateBoolType(self):
398+
typeItem = {
399+
"class": "H5T_ENUM",
400+
"base": {
401+
"base": "H5T_STD_I8LE",
402+
"class": "H5T_INTEGER"
403+
},
404+
"mapping": {
405+
"TRUE": 1,
406+
"FALSE": 0
407+
}
408+
}
409+
410+
typeSize = hdf5dtype.getItemSize(typeItem)
411+
self.assertEqual(typeSize, 1)
412+
dt = hdf5dtype.createDataType(typeItem)
413+
self.assertEqual(dt.name, 'bool')
414+
self.assertEqual(dt.kind, 'b')
415+
416+
417+
356418
def testCreateCompoundType(self):
357419
typeItem = {
358420
'class': 'H5T_COMPOUND', 'fields':

0 commit comments

Comments
 (0)