def __get_key_from_int(key: Union[str, int], column: MafColumnRecord) -> str: """Returns the name that should be used for the column and sets the column index if not already set""" column_index = int(key) if column_index < 0: raise KeyError # set the column_index on column if not already set, otherwise # ensure they are the same if column.column_index is None: column.column_index = column_index elif column_index != column.column_index: raise ValueError( f"Column index mismatch: {column.column_index} is not {column_index}" ) return column.key
def __setitem__(self, key: Union[int, str], column: MafColumnRecord) -> None: """If a record already exists with the column name `key`, we either check that the `column_index`es are the same, or set the `column_index` if it is not set on the record. Otherwise, if the `column_index` is not set and no existing record is found with the column name `key`, then append it, and set `column_index` in `column`. If the `column_index` is greater than the length, then extend the number of columns, inserting `None` for values for any columns between the old and new length; these columns will have no name. :param key: The key may be one of four things: 1. If an `int`, it is assumed to be the `column_index` of the column. The `column_index` of`column` will be set to `int(key)` if not already set. If already set, then `column.column_index` should equal `int(key)`. 2. If an `MafColumnRecord`, then the `MafColumnRecord` should have the same `key` as the provided column. 3. If `None`, then `None` will always be returned. 4. Otherwise, it should be the column name, and be the same as the `key` in the provided column. :param column: an instance of `MafColumnRecord`.""" if not isinstance(column, MafColumnRecord): raise TypeError(f"{type(column)} is not 'MafColumnRecord'") if isinstance(key, int): key = self.__get_key_from_int(key, column) elif isinstance(key, MafColumnRecord): # make sure the keys are the same key = self.__get_key_from_column(key, column) elif not isinstance(key, str): raise TypeError("Column name must be a string") elif column.key != key: raise ValueError( f"Adding a column with name '{column.key}' but key was '{key}'" ) assert key == column.key # if there already is a record with the same key, make sure that it has # the same column index, otherwise set the column index if the current # record doesn't have one. If there is no record with the same and the # column index is not set, set it as the next column in the list. if key in self.__columns_dict: if column.column_index is None: column.column_index = self.__columns_dict[key].column_index else: if self.__columns_dict[key].column_index != column.column_index: raise ValueError( f"Existing column's index '{self.__columns_dict[key].column_index}' does not match replacement column's index '{column.column_index}'" ) elif column.column_index is None: # set the column index to the next column column.column_index = len(self.__columns_list) self.__columns_dict[key] = column assert column.column_index is not None # extend the list if the index is out of range if len(self) <= column.column_index: num_more = column.column_index - len(self) + 1 self.__columns_list.extend([None] * num_more) # Developer Note: due to padding, the number of items in the dictionary # may be less than the number of items in the list. Use validate to # catch this later. self.__columns_list[column.column_index] = column