Consistency check for __setitem__ When assigning values to a subset of a Dataset, do consistency check beforehand to avoid leaving the dataset in a partially updated state when an error occurs.
(self, key, value)
| 1447 | raise ValueError(f"Unsupported key-type {type(key)}") |
| 1448 | |
| 1449 | def _setitem_check(self, key, value): |
| 1450 | """Consistency check for __setitem__ |
| 1451 | |
| 1452 | When assigning values to a subset of a Dataset, do consistency check beforehand |
| 1453 | to avoid leaving the dataset in a partially updated state when an error occurs. |
| 1454 | """ |
| 1455 | from xarray.core.dataarray import DataArray |
| 1456 | |
| 1457 | if isinstance(value, Dataset): |
| 1458 | missing_vars = [ |
| 1459 | name for name in value.data_vars if name not in self.data_vars |
| 1460 | ] |
| 1461 | if missing_vars: |
| 1462 | raise ValueError( |
| 1463 | f"Variables {missing_vars} in new values" |
| 1464 | f" not available in original dataset:\n{self}" |
| 1465 | ) |
| 1466 | elif not any(isinstance(value, t) for t in [DataArray, Number, str]): |
| 1467 | raise TypeError( |
| 1468 | "Dataset assignment only accepts DataArrays, Datasets, and scalars." |
| 1469 | ) |
| 1470 | |
| 1471 | new_value = Dataset() |
| 1472 | for name, var in self.items(): |
| 1473 | # test indexing |
| 1474 | try: |
| 1475 | var_k = var[key] |
| 1476 | except Exception as e: |
| 1477 | raise ValueError( |
| 1478 | f"Variable '{name}': indexer {key} not available" |
| 1479 | ) from e |
| 1480 | |
| 1481 | if isinstance(value, Dataset): |
| 1482 | val = value[name] |
| 1483 | else: |
| 1484 | val = value |
| 1485 | |
| 1486 | if isinstance(val, DataArray): |
| 1487 | # check consistency of dimensions |
| 1488 | for dim in val.dims: |
| 1489 | if dim not in var_k.dims: |
| 1490 | raise KeyError( |
| 1491 | f"Variable '{name}': dimension '{dim}' appears in new values " |
| 1492 | f"but not in the indexed original data" |
| 1493 | ) |
| 1494 | dims = tuple(dim for dim in var_k.dims if dim in val.dims) |
| 1495 | if dims != val.dims: |
| 1496 | raise ValueError( |
| 1497 | f"Variable '{name}': dimension order differs between" |
| 1498 | f" original and new data:\n{dims}\nvs.\n{val.dims}" |
| 1499 | ) |
| 1500 | else: |
| 1501 | val = np.array(val) |
| 1502 | |
| 1503 | # type conversion |
| 1504 | new_value[name] = duck_array_ops.astype(val, dtype=var_k.dtype, copy=False) |
| 1505 | |
| 1506 | # check consistency of dimension sizes and dimension coordinates |
no test coverage detected