Skip to content

Commit

Permalink
Run tests differently for h5py < 3
Browse files Browse the repository at this point in the history
  • Loading branch information
rly committed Sep 6, 2024
1 parent 2935d64 commit 9ecdf4f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/hdmf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ def update(self, other):

@docval_macro('array_data')
class StrDataset(h5py.Dataset):
"""Wrapper to decode strings on reading the dataset"""
"""Wrapper to decode strings on reading the dataset. Use only for h5py 3+."""
def __init__(self, dset, encoding, errors='strict'):
self.dset = dset
if encoding is None:
Expand Down
74 changes: 70 additions & 4 deletions tests/unit/build_tests/test_io_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

from tests.unit.helpers.utils import CORE_NAMESPACE, create_test_type_map

H5PY_3 = h5py.__version__.startswith('3')


class Bar(Container):

Expand Down Expand Up @@ -461,7 +463,8 @@ def test_build_3d_ndarray(self):
np.testing.assert_array_equal(builder.get('data').data, str_array_3d)
np.testing.assert_array_equal(builder.get('attr_array'), str_array_3d)

def test_build_1d_h5py_dataset(self):
@unittest.skipIf(not H5PY_3, "Use StrDataset only for h5py 3+")
def test_build_1d_h5py_3_dataset(self):
bar_spec = GroupSpec(
doc='A test group specification with a data type',
data_type_def='Bar',
Expand All @@ -485,14 +488,15 @@ def test_build_1d_h5py_dataset(self):
['aa', 'bb', 'cc', 'dd'],
dtype=h5py.special_dtype(vlen=str)
)
# wrap the dataset in a StrDataset to mimic how HDF5IO would read this dataset
# wrap the dataset in a StrDataset to mimic how HDF5IO would read this dataset with h5py 3+
dataset = StrDataset(f.create_dataset('data', data=str_array_1d), None)
bar_inst = Bar('my_bar', dataset, 'value1', 10, attr_array=dataset)
builder = type_map.build(bar_inst)
np.testing.assert_array_equal(builder.get('data').data, dataset[:])
np.testing.assert_array_equal(builder.get('attr_array'), dataset[:])

def test_build_3d_h5py_dataset(self):
@unittest.skipIf(not H5PY_3, "Use StrDataset only for h5py 3+")
def test_build_3d_h5py_3_dataset(self):
bar_spec = GroupSpec(
doc='A test group specification with a data type',
data_type_def='Bar',
Expand All @@ -516,13 +520,75 @@ def test_build_3d_h5py_dataset(self):
[[['aa', 'bb'], ['cc', 'dd']], [['ee', 'ff'], ['gg', 'hh']]],
dtype=h5py.special_dtype(vlen=str)
)
# wrap the dataset in a StrDataset to mimic how HDF5IO would read this dataset
# wrap the dataset in a StrDataset to mimic how HDF5IO would read this dataset with h5py 3+
dataset = StrDataset(f.create_dataset('data', data=str_array_3d), None)
bar_inst = Bar('my_bar', dataset, 'value1', 10, attr_array=dataset)
builder = type_map.build(bar_inst)
np.testing.assert_array_equal(builder.get('data').data, dataset[:])
np.testing.assert_array_equal(builder.get('attr_array'), dataset[:])

@unittest.skipIf(H5PY_3, "Create dataset differently for h5py < 3")
def test_build_1d_h5py_2_dataset(self):
bar_spec = GroupSpec(
doc='A test group specification with a data type',
data_type_def='Bar',
datasets=[
DatasetSpec(
doc='an example dataset',
dtype='text',
name='data',
shape=(None, ),
attributes=[AttributeSpec(name='attr2', doc='an example integer attribute', dtype='int')],
)
],
attributes=[AttributeSpec(name='attr_array', doc='an example array attribute', dtype='text',
shape=(None, ))],
)
type_map = self.customSetUp(bar_spec)
type_map.register_map(Bar, BarMapper)
# create in-memory hdf5 file that is discarded after closing
with h5py.File("test.h5", "w", driver="core", backing_store=False) as f:
str_array_1d = np.array(
['aa', 'bb', 'cc', 'dd'],
dtype=h5py.special_dtype(vlen=str)
)
dataset = f.create_dataset('data', data=str_array_1d)
bar_inst = Bar('my_bar', dataset, 'value1', 10, attr_array=dataset)
builder = type_map.build(bar_inst)
np.testing.assert_array_equal(builder.get('data').data, dataset[:])
np.testing.assert_array_equal(builder.get('attr_array'), dataset[:])

@unittest.skipIf(H5PY_3, "Create dataset differently for h5py < 3")
def test_build_3d_h5py_2_dataset(self):
bar_spec = GroupSpec(
doc='A test group specification with a data type',
data_type_def='Bar',
datasets=[
DatasetSpec(
doc='an example dataset',
dtype='text',
name='data',
shape=(None, None, None),
attributes=[AttributeSpec(name='attr2', doc='an example integer attribute', dtype='int')],
)
],
attributes=[AttributeSpec(name='attr_array', doc='an example array attribute', dtype='text',
shape=(None, None, None))],
)
type_map = self.customSetUp(bar_spec)
type_map.register_map(Bar, BarMapper)
# create in-memory hdf5 file that is discarded after closing
with h5py.File("test.h5", "w", driver="core", backing_store=False) as f:
str_array_3d = np.array(
[[['aa', 'bb'], ['cc', 'dd']], [['ee', 'ff'], ['gg', 'hh']]],
dtype=h5py.special_dtype(vlen=str)
)
dataset = f.create_dataset('data', data=str_array_3d)
bar_inst = Bar('my_bar', dataset, 'value1', 10, attr_array=dataset)
builder = type_map.build(bar_inst)
np.testing.assert_array_equal(builder.get('data').data, dataset[:])
np.testing.assert_array_equal(builder.get('attr_array'), dataset[:])

def test_build_dataio(self):
bar_spec = GroupSpec('A test group specification with a data type',
data_type_def='Bar',
Expand Down

0 comments on commit 9ecdf4f

Please sign in to comment.