Disallows loading or coercing to an index but does support concatenation / stacking.
| 154 | |
| 155 | |
| 156 | class ConcatenatableArray: |
| 157 | """Disallows loading or coercing to an index but does support concatenation / stacking.""" |
| 158 | |
| 159 | def __init__(self, array): |
| 160 | # use ._array instead of .array because we don't want this to be accessible even to xarray's internals (e.g. create_default_index_implicit) |
| 161 | self._array = array |
| 162 | |
| 163 | @property |
| 164 | def dtype(self: Any) -> np.dtype: |
| 165 | return self._array.dtype |
| 166 | |
| 167 | @property |
| 168 | def shape(self: Any) -> tuple[int, ...]: |
| 169 | return self._array.shape |
| 170 | |
| 171 | @property |
| 172 | def ndim(self: Any) -> int: |
| 173 | return self._array.ndim |
| 174 | |
| 175 | def __repr__(self: Any) -> str: |
| 176 | return f"{type(self).__name__}(array={self._array!r})" |
| 177 | |
| 178 | def get_duck_array(self): |
| 179 | raise UnexpectedDataAccess("Tried accessing data") |
| 180 | |
| 181 | def __array__( |
| 182 | self, dtype: np.typing.DTypeLike | None = None, /, *, copy: bool | None = None |
| 183 | ) -> np.ndarray: |
| 184 | raise UnexpectedDataAccess("Tried accessing data") |
| 185 | |
| 186 | def __getitem__(self, key) -> Self: |
| 187 | """Some cases of concat require supporting expanding dims by dimensions of size 1""" |
| 188 | # see https://data-apis.org/array-api/2022.12/API_specification/indexing.html#multi-axis-indexing |
| 189 | arr = self._array |
| 190 | for axis, indexer_1d in enumerate(key): |
| 191 | if indexer_1d is None: |
| 192 | arr = np.expand_dims(arr, axis) |
| 193 | elif indexer_1d is Ellipsis: |
| 194 | pass |
| 195 | else: |
| 196 | raise UnexpectedDataAccess("Tried accessing data.") |
| 197 | return type(self)(arr) |
| 198 | |
| 199 | def __eq__(self, other: Self) -> Self: # type: ignore[override] |
| 200 | return type(self)(self._array == other._array) |
| 201 | |
| 202 | def __array_function__(self, func, types, args, kwargs) -> Any: |
| 203 | if func not in CONCATENATABLEARRAY_HANDLED_ARRAY_FUNCTIONS: |
| 204 | return NotImplemented |
| 205 | |
| 206 | # Note: this allows subclasses that don't override |
| 207 | # __array_function__ to handle ManifestArray objects |
| 208 | if not all(issubclass(t, ConcatenatableArray) for t in types): |
| 209 | return NotImplemented |
| 210 | |
| 211 | return CONCATENATABLEARRAY_HANDLED_ARRAY_FUNCTIONS[func](*args, **kwargs) |
| 212 | |
| 213 | def __array_ufunc__(self, ufunc, method, *inputs, **kwargs) -> Any: |
no outgoing calls
searching dependent graphs…