1import abc 2import weakref 3 4 5class BTBaseList(object, metaclass=abc.ABCMeta): 6 def __init__(self, table, value): 7 self._table = table 8 self._value = self._validate(list(value)) 9 10 @property 11 def _table(self): 12 return self._table_ref() 13 14 @_table.setter 15 def _table(self, value): 16 self._table_ref = weakref.ref(value) 17 18 @property 19 def value(self): 20 return self._value 21 22 def __len__(self): 23 return len(self._value) 24 25 def __iter__(self): 26 return iter(self._value) 27 28 def __next__(self): 29 return next(self._value) 30 31 def __repr__(self): 32 class_ = type(self).__name__ 33 data = ", ".join(repr(v) for v in self._value) 34 return "{}<{}>".format(class_, data) 35 36 def __eq__(self, other): 37 if len(self) != len(other): 38 return False 39 for i, j in zip(self, other): 40 if i != j: 41 return False 42 return True 43 44 def __contains__(self, item): 45 """Returns whether `item` is present""" 46 return item in self._value 47 48 def _append(self, item): 49 self._value.append(item) 50 51 def _insert(self, i, item): 52 self._value.insert(i, item) 53 54 def _pop(self, i=-1): 55 return self._value.pop(self._get_canonical_key(i)) 56 57 def _remove(self, item): 58 self._value.remove(item) 59 60 def _reverse(self): 61 self._value.reverse() 62 63 def _sort(self, key, reverse=False): 64 self._value.sort(key=key, reverse=reverse) 65 66 def _clear(self): 67 self._value.clear() 68 69 def count(self, item): 70 return self._value.count(item) 71 72 def index(self, item, *args): 73 """Returns the index of `item`""" 74 try: 75 return self._value.index(item, *args) 76 except ValueError: 77 raise KeyError("Key {} is not available".format(item)) 78 79 def __getitem__(self, key): 80 """Returns item at index or header `key`""" 81 return self._value[self._get_canonical_key(key)] 82 83 def __setitem__(self, key, value): 84 """Updates item at index or header `key`""" 85 self._value[self._get_canonical_key(key)] = value 86 87 def __delitem__(self, key): 88 del self._value[self._get_canonical_key(key)] 89 90 def _validate(self, value): 91 if len(value) != self._get_ideal_length(): 92 raise ValueError( 93 ("'Expected iterable of length {}, " "got {}").format( 94 self._get_ideal_length(), len(value) 95 ) 96 ) 97 return value 98 99 @abc.abstractmethod 100 def _get_canonical_key(self, key): 101 pass 102 103 @abc.abstractmethod 104 def _get_ideal_length(self): 105 pass 106 107 108class BTBaseRow(BTBaseList): 109 def _get_canonical_key(self, key): 110 return self._table.columns._canonical_key(key) 111 112 def _get_ideal_length(self): 113 return self._table._ncol 114 115 def _validate(self, value): 116 if self._get_ideal_length() == 0 and len(value) > 0: 117 self._table.columns._reset_state(len(value)) 118 return super(BTBaseRow, self)._validate(value) 119 120 121class BTBaseColumn(BTBaseList): 122 def _get_canonical_key(self, key): 123 return self._table.rows._canonical_key(key) 124 125 def _get_ideal_length(self): 126 return len(self._table._data) 127 128 def _validate(self, value): 129 if self._get_ideal_length() == 0 and len(value) > 0: 130 self._table.rows._reset_state(len(value)) 131 return super(BTBaseColumn, self)._validate(value) 132