@@ -521,7 +521,7 @@ def _init_class_columns(self):
521521 description = col ['description' ],
522522 index = col .get ('index' , False ),
523523 table = col .get ('table' , False ),
524- col_cls = col .get ('class' , VectorData ),
524+ col_cls = col .get ('class' ),
525525 # Pass through extra kwargs for add_column that subclasses may have added
526526 ** {k : col [k ] for k in col .keys ()
527527 if k not in DynamicTable .__reserved_colspec_keys })
@@ -564,10 +564,13 @@ def _set_dtr_targets(self, target_tables: dict):
564564 if not column_conf .get ('table' , False ):
565565 raise ValueError ("Column '%s' must be a DynamicTableRegion to have a target table."
566566 % colname )
567- self .add_column (name = column_conf ['name' ],
568- description = column_conf ['description' ],
569- index = column_conf .get ('index' , False ),
570- table = True )
567+ self .add_column (
568+ name = column_conf ['name' ],
569+ description = column_conf ['description' ],
570+ index = column_conf .get ('index' , False ),
571+ table = True ,
572+ col_cls = column_conf .get ('class' ),
573+ )
571574 if isinstance (self [colname ], VectorIndex ):
572575 col = self [colname ].target
573576 else :
@@ -681,7 +684,7 @@ def add_row(self, **kwargs):
681684 index = col .get ('index' , False ),
682685 table = col .get ('table' , False ),
683686 enum = col .get ('enum' , False ),
684- col_cls = col .get ('class' , VectorData ),
687+ col_cls = col .get ('class' ),
685688 # Pass through extra keyword arguments for add_column that
686689 # subclasses may have added
687690 ** {k : col [k ] for k in col .keys ()
@@ -753,7 +756,7 @@ def __eq__(self, other):
753756 'default' : False },
754757 {'name' : 'enum' , 'type' : (bool , 'array_data' ), 'default' : False ,
755758 'doc' : ('whether or not this column contains data from a fixed set of elements' )},
756- {'name' : 'col_cls' , 'type' : type , 'default' : VectorData ,
759+ {'name' : 'col_cls' , 'type' : type , 'default' : None ,
757760 'doc' : ('class to use to represent the column data. If table=True, this field is ignored and a '
758761 'DynamicTableRegion object is used. If enum=True, this field is ignored and a EnumData '
759762 'object is used.' )},
@@ -805,29 +808,39 @@ def add_column(self, **kwargs): # noqa: C901
805808 % (name , self .__class__ .__name__ , spec_index ))
806809 warn (msg , stacklevel = 3 )
807810
808- spec_col_cls = self .__uninit_cols [name ].get ('class' , VectorData )
809- if col_cls != spec_col_cls :
810- msg = ("Column '%s' is predefined in %s with class=%s which does not match the entered "
811- "col_cls argument. The predefined class spec will be ignored. "
812- "Please ensure the new column complies with the spec. "
813- "This will raise an error in a future version of HDMF."
814- % (name , self .__class__ .__name__ , spec_col_cls ))
815- warn (msg , stacklevel = 2 )
816-
817811 ckwargs = dict (kwargs )
818812
819813 # Add table if it's been specified
820814 if table and enum :
821815 raise ValueError ("column '%s' cannot be both a table region "
822816 "and come from an enumerable set of elements" % name )
817+ # Update col_cls if table is specified
823818 if table is not False :
824- col_cls = DynamicTableRegion
819+ if col_cls is None :
820+ col_cls = DynamicTableRegion
825821 if isinstance (table , DynamicTable ):
826822 ckwargs ['table' ] = table
823+ # Update col_cls if enum is specified
827824 if enum is not False :
828- col_cls = EnumData
825+ if col_cls is None :
826+ col_cls = EnumData
829827 if isinstance (enum , (list , tuple , np .ndarray , VectorData )):
830828 ckwargs ['elements' ] = enum
829+ # Update col_cls to the default VectorData if col_cls is None
830+ if col_cls is None :
831+ col_cls = VectorData
832+
833+ if name in self .__uninit_cols : # column is a predefined optional column from the spec
834+ # check the given values against the predefined optional column spec. if they do not match, raise a warning
835+ # and ignore the given arguments. users should not be able to override these values
836+ spec_col_cls = self .__uninit_cols [name ].get ('class' )
837+ if spec_col_cls is not None and col_cls != spec_col_cls :
838+ msg = ("Column '%s' is predefined in %s with class=%s which does not match the entered "
839+ "col_cls argument. The predefined class spec will be ignored. "
840+ "Please ensure the new column complies with the spec. "
841+ "This will raise an error in a future version of HDMF."
842+ % (name , self .__class__ .__name__ , spec_col_cls ))
843+ warn (msg , stacklevel = 2 )
831844
832845 # If the user provided a list of lists that needs to be indexed, then we now need to flatten the data
833846 # We can only create the index actual VectorIndex once we have the VectorData column so we compute
@@ -873,7 +886,7 @@ def add_column(self, **kwargs): # noqa: C901
873886 if col in self .__uninit_cols :
874887 self .__uninit_cols .pop (col )
875888
876- if col_cls is EnumData :
889+ if issubclass ( col_cls , EnumData ) :
877890 columns .append (col .elements )
878891 col .elements .parent = self
879892
0 commit comments