Skip to content

Commit

Permalink
Fix issue with empty array colnames for DynamicTable (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
rly authored Jun 15, 2020
1 parent 93eec0a commit 3fa0587
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# HDMF Changelog

## HDMF 1.6.4 (Upcoming)

### Bug fixes:
- Fix validation of empty arrays and scalar attributes. @rly (#377)
- Fix issue with constructing `DynamicTable` with empty array colnames. @rly (#379)

## HDMF 1.6.3 (June 9, 2020)

### Internal improvements
Expand Down
2 changes: 1 addition & 1 deletion src/hdmf/backends/hdf5/h5tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ def __read_dataset(self, h5obj, name=None):
kwargs["data"] = scalar
elif ndims == 1:
d = None
if h5obj.dtype.kind == 'O':
if h5obj.dtype.kind == 'O' and len(h5obj) > 0:
elem1 = h5obj[0]
if isinstance(elem1, (str, bytes)):
d = h5obj
Expand Down
12 changes: 7 additions & 5 deletions src/hdmf/common/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,13 @@ def __init__(self, **kwargs): # noqa: C901

self.id = id

if colnames is None:
# NOTE: self.colnames and self.columns are always tuples
# if kwarg colnames is an h5dataset, self.colnames is still a tuple
if colnames is None or len(colnames) == 0:
if columns is None:
# make placeholder for columns if nothing was given
self.colnames = list()
self.columns = list()
self.colnames = tuple()
self.columns = tuple()
else:
# Figure out column names if columns were given
tmp = list()
Expand All @@ -268,7 +270,7 @@ def __init__(self, **kwargs): # noqa: C901
continue
tmp.append(col.name)
self.colnames = tuple(tmp)
self.columns = columns
self.columns = tuple(columns)
else:
# Calculate the order of column names
if columns is None:
Expand Down Expand Up @@ -304,7 +306,7 @@ def __init__(self, **kwargs): # noqa: C901
pos = order[col.target.name]
tmp[pos] = col
tmp[pos+1] = col.target
self.columns = list(tmp)
self.columns = tuple(tmp)

# to make generating DataFrames and Series easier
col_dict = dict()
Expand Down
18 changes: 16 additions & 2 deletions tests/unit/common/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ def with_spec(self):
return table

def check_empty_table(self, table):
self.assertIsInstance(table.columns, tuple)
self.assertIsInstance(table.columns[0], VectorData)
self.assertEqual(len(table.columns), 3)
self.assertEqual(table.colnames, ('foo', 'bar', 'baz'))
self.assertTupleEqual(table.colnames, ('foo', 'bar', 'baz'))

def test_constructor_table_columns(self):
table = self.with_table_columns()
Expand Down Expand Up @@ -134,7 +135,7 @@ def test_get_item(self):
def test_add_column(self):
table = self.with_spec()
table.add_column(name='qux', description='qux column')
self.assertEqual(table.colnames, ('foo', 'bar', 'baz', 'qux'))
self.assertTupleEqual(table.colnames, ('foo', 'bar', 'baz', 'qux'))
self.assertTrue(hasattr(table, 'qux'))

def test_add_column_twice(self):
Expand Down Expand Up @@ -403,6 +404,11 @@ def test_init_columns_existing_attr(self):
with self.assertWarnsWith(UserWarning, msg):
DynamicTable("test_table", 'a test table', columns=cols)

def test_colnames_none(self):
table = DynamicTable('table0', 'an example table')
self.assertTupleEqual(table.colnames, tuple())
self.assertTupleEqual(table.columns, tuple())


class TestDynamicTableRoundTrip(H5RoundTripMixin, TestCase):

Expand All @@ -417,6 +423,14 @@ def setUpContainer(self):
return table


class TestEmptyDynamicTableRoundTrip(H5RoundTripMixin, TestCase):
"""Test roundtripping a DynamicTable with no rows and no columns."""

def setUpContainer(self):
table = DynamicTable('table0', 'an example table')
return table


class TestDynamicTableRegion(TestCase):

def setUp(self):
Expand Down

0 comments on commit 3fa0587

Please sign in to comment.