From 6905781a3a01b66ca1be3f141f1936dbc6f7438d Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Tue, 31 Oct 2023 15:25:01 -0700 Subject: [PATCH 01/21] _gather_columns agnostic search --- src/hdmf/common/table.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 58f0470e1..f2c809d46 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -278,11 +278,16 @@ def __gather_columns(cls, name, bases, classdict): msg = "'__columns__' must be of type tuple, found %s" % type(cls.__columns__) raise TypeError(msg) - if (len(bases) and 'DynamicTable' in globals() and issubclass(bases[-1], Container) - and bases[-1].__columns__ is not cls.__columns__): - new_columns = list(cls.__columns__) - new_columns[0:0] = bases[-1].__columns__ # prepend superclass columns to new_columns - cls.__columns__ = tuple(new_columns) + if len(bases) and 'DynamicTable' in globals(): + for item in bases: + if issubclass(item, Container): + try: + if item.__columns__ is not cls.__columns__: + new_columns = list(cls.__columns__) + new_columns[0:0] = bases[-1].__columns__ # prepend superclass columns to new_columns + cls.__columns__ = tuple(new_columns) + except AttributeError: + continue @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 {'name': 'description', 'type': str, 'doc': 'a description of what is in this table'}, From fe89d2ab8cf3694539a931f469711e301c7b870b Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Tue, 31 Oct 2023 16:04:45 -0700 Subject: [PATCH 02/21] Update table.py Co-authored-by: Ryan Ly --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index f2c809d46..bd15f5dd3 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -284,7 +284,7 @@ def __gather_columns(cls, name, bases, classdict): try: if item.__columns__ is not cls.__columns__: new_columns = list(cls.__columns__) - new_columns[0:0] = bases[-1].__columns__ # prepend superclass columns to new_columns + new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) except AttributeError: continue From e0d540c95fd1186fd95552bd13e94d4bddee2e58 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Wed, 1 Nov 2023 08:41:26 -0700 Subject: [PATCH 03/21] Update src/hdmf/common/table.py Co-authored-by: Ryan Ly --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index bd15f5dd3..ed9d42313 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -286,7 +286,7 @@ def __gather_columns(cls, name, bases, classdict): new_columns = list(cls.__columns__) new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) - except AttributeError: + except AttributeError: # raises error when "__columns__" is not an attr of item continue @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 From 1f516dc1b4f36c37f281635cf93b967f0315425a Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 Nov 2023 11:13:00 -0700 Subject: [PATCH 04/21] checkpoint --- src/hdmf/common/table.py | 5 ++++- tests/unit/helpers/utils.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index ed9d42313..5f6c9aacd 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -279,13 +279,16 @@ def __gather_columns(cls, name, bases, classdict): raise TypeError(msg) if len(bases) and 'DynamicTable' in globals(): - for item in bases: + for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last if issubclass(item, Container): try: if item.__columns__ is not cls.__columns__: + if cls.__name__ == 'PlaneSegmentation': + breakpoint() new_columns = list(cls.__columns__) new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) + break except AttributeError: # raises error when "__columns__" is not an attr of item continue diff --git a/tests/unit/helpers/utils.py b/tests/unit/helpers/utils.py index 5d4bf16ec..706c7ae54 100644 --- a/tests/unit/helpers/utils.py +++ b/tests/unit/helpers/utils.py @@ -653,3 +653,28 @@ class CustomSpecNamespace(SpecNamespace): @classmethod def types_key(cls): return cls.__types_key + +class FooExtendDynamicTable0(DynamicTable): + """ + Within PyNWB, PlaneSegmentation extends DynamicTable and sets __columns__. This class is a helper + class for testing and is directly meant to test __gather_columns, i.e., class generation, downstream. + """ + __columns__ = ( + {'name': 'col1', 'description': '...'}, + {'name': 'col2', 'description': '...'}, + ) + + +class FooExtendDynamicTable1(FooExtendDynamicTable0): + """ + In extensions, users can create new classes that inherit from classes that inherit from DynamicTable. + This is a helper class for testing and is directly meant to test __gather_columns, i.e., + class generation, downstream. + """ + __columns__ = ( + {'name': 'col3', 'description': '...'}, + {'name': 'col4', 'description': '...'}, + ) + +class FooExtendDynamicTable2(FooExtendDynamicTable2): + pass From b86e6d9f11cc6c0a4366cb6f4c517a513e2bc432 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 Nov 2023 13:23:27 -0700 Subject: [PATCH 05/21] tests --- tests/unit/common/test_table.py | 16 ++++++++++++++++ tests/unit/helpers/utils.py | 19 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/tests/unit/common/test_table.py b/tests/unit/common/test_table.py index 4f0ab6af5..b1c2dabaa 100644 --- a/tests/unit/common/test_table.py +++ b/tests/unit/common/test_table.py @@ -2676,3 +2676,19 @@ def test_list_prev_data_inc_precision_2steps(self): index.add_vector(list(range(65536 - 255))) self.assertEqual(index.data[0], 255) # make sure the 255 is upgraded self.assertEqual(type(index.data[0]), np.uint32) + +from tests.unit.helpers.utils import FooExtendDynamicTable0, FooExtendDynamicTable1, FooExtendDynamicTable2 +class TestDynamicTableSubclassColumns(TestCase): + def setUp(self): + self.foo1 = FooExtendDynamicTable0() + self.foo2 = FooExtendDynamicTable1() + self.foo3 = FooExtendDynamicTable2() + + def test_columns(self): + self.assertEqual(self.foo1.__columns__, + ({'name': 'col1', 'description': '...'}, {'name': 'col2', 'description': '...'})) + self.assertEqual(self.foo2.__columns__, + ({'name': 'col1', 'description': '...'}, {'name': 'col2', 'description': '...'}, + {'name': 'col3', 'description': '...'}, {'name': 'col4', 'description': '...'}) +) + self.assertEqual(self.foo2.__columns__, self.foo3.__columns__) diff --git a/tests/unit/helpers/utils.py b/tests/unit/helpers/utils.py index 706c7ae54..01ea0b2e3 100644 --- a/tests/unit/helpers/utils.py +++ b/tests/unit/helpers/utils.py @@ -3,6 +3,7 @@ from copy import copy, deepcopy from hdmf.build import BuildManager, ObjectMapper, TypeMap +from hdmf.common.table import DynamicTable from hdmf.container import Container, HERDManager, Data from hdmf.spec import ( AttributeSpec, @@ -664,6 +665,11 @@ class for testing and is directly meant to test __gather_columns, i.e., class ge {'name': 'col2', 'description': '...'}, ) + def __init__(self, **kwargs): + kwargs['name'] = 'foo0' + kwargs['description'] = '...' + super().__init__(**kwargs) + class FooExtendDynamicTable1(FooExtendDynamicTable0): """ @@ -676,5 +682,14 @@ class generation, downstream. {'name': 'col4', 'description': '...'}, ) -class FooExtendDynamicTable2(FooExtendDynamicTable2): - pass + def __init__(self, **kwargs): + kwargs['name'] = 'foo1' + kwargs['description'] = '...' + super().__init__(**kwargs) + + +class FooExtendDynamicTable2(FooExtendDynamicTable1): + def __init__(self, **kwargs): + kwargs['name'] = 'foo2' + kwargs['description'] = '...' + super().__init__(**kwargs) From 171480334e73be9b0204559cc579c6e15c9454a3 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 Nov 2023 13:24:18 -0700 Subject: [PATCH 06/21] format --- tests/unit/common/test_table.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/common/test_table.py b/tests/unit/common/test_table.py index b1c2dabaa..eae421ff8 100644 --- a/tests/unit/common/test_table.py +++ b/tests/unit/common/test_table.py @@ -15,7 +15,7 @@ from hdmf.utils import StrDataset from hdmf.data_utils import DataChunkIterator -from tests.unit.helpers.utils import get_temp_filepath +from tests.unit.helpers.utils import get_temp_filepath, FooExtendDynamicTable0, FooExtendDynamicTable1, FooExtendDynamicTable2 try: import linkml_runtime # noqa: F401 @@ -2677,7 +2677,7 @@ def test_list_prev_data_inc_precision_2steps(self): self.assertEqual(index.data[0], 255) # make sure the 255 is upgraded self.assertEqual(type(index.data[0]), np.uint32) -from tests.unit.helpers.utils import FooExtendDynamicTable0, FooExtendDynamicTable1, FooExtendDynamicTable2 + class TestDynamicTableSubclassColumns(TestCase): def setUp(self): self.foo1 = FooExtendDynamicTable0() From 1b8b8113343dbbb80d785f5ed8abc161c0aaf801 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Wed, 1 Nov 2023 23:02:29 -0700 Subject: [PATCH 07/21] Update table.py --- src/hdmf/common/table.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 5f6c9aacd..92b443936 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -283,8 +283,6 @@ def __gather_columns(cls, name, bases, classdict): if issubclass(item, Container): try: if item.__columns__ is not cls.__columns__: - if cls.__name__ == 'PlaneSegmentation': - breakpoint() new_columns = list(cls.__columns__) new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) From 365b9c5045900f5565abdf07bf2f7a46cfc1ce91 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 08:25:37 -0800 Subject: [PATCH 08/21] ruff --- tests/unit/common/test_table.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/common/test_table.py b/tests/unit/common/test_table.py index eae421ff8..1854fae22 100644 --- a/tests/unit/common/test_table.py +++ b/tests/unit/common/test_table.py @@ -15,7 +15,8 @@ from hdmf.utils import StrDataset from hdmf.data_utils import DataChunkIterator -from tests.unit.helpers.utils import get_temp_filepath, FooExtendDynamicTable0, FooExtendDynamicTable1, FooExtendDynamicTable2 +from tests.unit.helpers.utils import (get_temp_filepath, FooExtendDynamicTable0, + FooExtendDynamicTable1, FooExtendDynamicTable2) try: import linkml_runtime # noqa: F401 From d9561946627022ce3b23d9dcde78f5287e6c0533 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 09:07:02 -0800 Subject: [PATCH 09/21] edits --- src/hdmf/common/table.py | 15 ++++++--------- src/hdmf/utils.py | 4 ++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 92b443936..2e2f09071 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -268,7 +268,7 @@ class DynamicTable(Container): @ExtenderMeta.pre_init def __gather_columns(cls, name, bases, classdict): - r""" + """ Gather columns from the *\_\_columns\_\_* class attribute and add them to the class. This classmethod will be called during class declaration in the metaclass to automatically @@ -281,14 +281,11 @@ def __gather_columns(cls, name, bases, classdict): if len(bases) and 'DynamicTable' in globals(): for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last if issubclass(item, Container): - try: - if item.__columns__ is not cls.__columns__: - new_columns = list(cls.__columns__) - new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns - cls.__columns__ = tuple(new_columns) - break - except AttributeError: # raises error when "__columns__" is not an attr of item - continue + if item.__columns__ is not cls.__columns__: + new_columns = list(cls.__columns__) + new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns + cls.__columns__ = tuple(new_columns) + break @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 {'name': 'description', 'type': str, 'doc': 'a description of what is in this table'}, diff --git a/src/hdmf/utils.py b/src/hdmf/utils.py index d85eb5c8c..21f8f5c23 100644 --- a/src/hdmf/utils.py +++ b/src/hdmf/utils.py @@ -837,6 +837,10 @@ class ExtenderMeta(ABCMeta): @classmethod def pre_init(cls, func): + """ + A decorator that sets a '__preinit' attribute on the target function and + then returns the function as a classmethod. + """ setattr(func, cls.__preinit, True) return classmethod(func) From a8446507678e75ffd366ed0bce9680e56b67bc96 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:07:14 +0000 Subject: [PATCH 10/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/hdmf/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/utils.py b/src/hdmf/utils.py index 21f8f5c23..e2686912a 100644 --- a/src/hdmf/utils.py +++ b/src/hdmf/utils.py @@ -839,7 +839,7 @@ class ExtenderMeta(ABCMeta): def pre_init(cls, func): """ A decorator that sets a '__preinit' attribute on the target function and - then returns the function as a classmethod. + then returns the function as a classmethod. """ setattr(func, cls.__preinit, True) return classmethod(func) From 699bec7a458014bc8929e29d45a20c39962866d3 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 09:25:14 -0800 Subject: [PATCH 11/21] edit --- src/hdmf/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/utils.py b/src/hdmf/utils.py index 21f8f5c23..e2686912a 100644 --- a/src/hdmf/utils.py +++ b/src/hdmf/utils.py @@ -839,7 +839,7 @@ class ExtenderMeta(ABCMeta): def pre_init(cls, func): """ A decorator that sets a '__preinit' attribute on the target function and - then returns the function as a classmethod. + then returns the function as a classmethod. """ setattr(func, cls.__preinit, True) return classmethod(func) From a4371d105c5a368442309b837e2743189882790c Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 09:28:40 -0800 Subject: [PATCH 12/21] edit --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 2e2f09071..720afa060 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -268,7 +268,7 @@ class DynamicTable(Container): @ExtenderMeta.pre_init def __gather_columns(cls, name, bases, classdict): - """ + r""" Gather columns from the *\_\_columns\_\_* class attribute and add them to the class. This classmethod will be called during class declaration in the metaclass to automatically From ca05060a35bc17d0bf6eda583a1c2f0b752d4432 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Mon, 6 Nov 2023 13:01:02 -0800 Subject: [PATCH 13/21] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6d4b8591..47c9c2d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # HDMF Changelog +## HDMF 3.11.1 (Upcoming) + +### Minor Improvements +- Updated `__gather_columns` to ignore the order of bases when generating columns from the super class. @mavaylon1 [#991](https://github.com/hdmf-dev/hdmf/pull/991) + ## HDMF 3.11.0 (October 30, 2023) ### Enhancements From c454c6ebb1259c0eb814d938439f57755a0c7fd7 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:06:37 -0800 Subject: [PATCH 14/21] try --- src/hdmf/common/table.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 720afa060..92b443936 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -281,11 +281,14 @@ def __gather_columns(cls, name, bases, classdict): if len(bases) and 'DynamicTable' in globals(): for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last if issubclass(item, Container): - if item.__columns__ is not cls.__columns__: - new_columns = list(cls.__columns__) - new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns - cls.__columns__ = tuple(new_columns) - break + try: + if item.__columns__ is not cls.__columns__: + new_columns = list(cls.__columns__) + new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns + cls.__columns__ = tuple(new_columns) + break + except AttributeError: # raises error when "__columns__" is not an attr of item + continue @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 {'name': 'description', 'type': str, 'doc': 'a description of what is in this table'}, From 3867facc055216d6b9616c68996866ab335b1c50 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:07:01 -0800 Subject: [PATCH 15/21] try --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 92b443936..0878acd8f 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -287,7 +287,7 @@ def __gather_columns(cls, name, bases, classdict): new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) break - except AttributeError: # raises error when "__columns__" is not an attr of item + except AttributeError: continue @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 From 0cd1eb87caada487a8cdffc1263b20cb44ef9072 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:23:00 -0800 Subject: [PATCH 16/21] try --- src/hdmf/common/table.py | 1 + tests/unit/helpers/utils.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 0878acd8f..e9009fa5f 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -279,6 +279,7 @@ def __gather_columns(cls, name, bases, classdict): raise TypeError(msg) if len(bases) and 'DynamicTable' in globals(): + breakpoint() for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last if issubclass(item, Container): try: diff --git a/tests/unit/helpers/utils.py b/tests/unit/helpers/utils.py index 01ea0b2e3..8705fdb51 100644 --- a/tests/unit/helpers/utils.py +++ b/tests/unit/helpers/utils.py @@ -4,7 +4,7 @@ from hdmf.build import BuildManager, ObjectMapper, TypeMap from hdmf.common.table import DynamicTable -from hdmf.container import Container, HERDManager, Data +from hdmf.container import Container, HERDManager, Data, MultiContainerInterface from hdmf.spec import ( AttributeSpec, DatasetSpec, @@ -688,7 +688,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) -class FooExtendDynamicTable2(FooExtendDynamicTable1): +class FooExtendDynamicTable2(FooExtendDynamicTable1, MultiContainerInterface): def __init__(self, **kwargs): kwargs['name'] = 'foo2' kwargs['description'] = '...' From 38d1b2f9ab51b89c9b83a1580a2489739771a830 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:24:03 -0800 Subject: [PATCH 17/21] try --- src/hdmf/common/table.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index e9009fa5f..0878acd8f 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -279,7 +279,6 @@ def __gather_columns(cls, name, bases, classdict): raise TypeError(msg) if len(bases) and 'DynamicTable' in globals(): - breakpoint() for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last if issubclass(item, Container): try: From f0c419698a0f9ad8198d348c3cb43b7bd7f2f907 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:31:41 -0800 Subject: [PATCH 18/21] try --- tests/unit/helpers/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unit/helpers/utils.py b/tests/unit/helpers/utils.py index 8705fdb51..e03815afe 100644 --- a/tests/unit/helpers/utils.py +++ b/tests/unit/helpers/utils.py @@ -689,6 +689,13 @@ def __init__(self, **kwargs): class FooExtendDynamicTable2(FooExtendDynamicTable1, MultiContainerInterface): + __clsconf__ = { + 'add': '...', + 'get': '...', + 'create': '...', + 'attr': '...' + } + def __init__(self, **kwargs): kwargs['name'] = 'foo2' kwargs['description'] = '...' From 219cb537fa7fbba7f3762335e852555427e516b1 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:37:42 -0800 Subject: [PATCH 19/21] try --- tests/unit/helpers/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/helpers/utils.py b/tests/unit/helpers/utils.py index e03815afe..0f4b3c4bf 100644 --- a/tests/unit/helpers/utils.py +++ b/tests/unit/helpers/utils.py @@ -693,6 +693,7 @@ class FooExtendDynamicTable2(FooExtendDynamicTable1, MultiContainerInterface): 'add': '...', 'get': '...', 'create': '...', + 'type': Container, 'attr': '...' } From 8fbf4a5914828bb0ac1438b42d2a558c97dcc28b Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 6 Nov 2023 13:57:32 -0800 Subject: [PATCH 20/21] note --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 0878acd8f..595f74905 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -287,7 +287,7 @@ def __gather_columns(cls, name, bases, classdict): new_columns[0:0] = item.__columns__ # prepend superclass columns to new_columns cls.__columns__ = tuple(new_columns) break - except AttributeError: + except AttributeError: # raises error when "__columns__" is not an attr of item continue @docval({'name': 'name', 'type': str, 'doc': 'the name of this table'}, # noqa: C901 From c6bf52c554a5f90d8fb95b35051a4405b3f561b4 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Mon, 6 Nov 2023 20:44:03 -0800 Subject: [PATCH 21/21] Update table.py Co-authored-by: Ryan Ly --- src/hdmf/common/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdmf/common/table.py b/src/hdmf/common/table.py index 595f74905..e6f492022 100644 --- a/src/hdmf/common/table.py +++ b/src/hdmf/common/table.py @@ -279,7 +279,7 @@ def __gather_columns(cls, name, bases, classdict): raise TypeError(msg) if len(bases) and 'DynamicTable' in globals(): - for item in bases[::-1]: # reverse the bases tuple as the code suggest it should be last + for item in bases[::-1]: # look for __columns__ in the base classes, closest first if issubclass(item, Container): try: if item.__columns__ is not cls.__columns__: