| 1120 | zarr.consolidate_metadata(self.zarr_group.store, **kwargs) |
| 1121 | |
| 1122 | def _open_existing_array(self, *, name) -> ZarrArray: |
| 1123 | import zarr |
| 1124 | from zarr import Array as ZarrArray |
| 1125 | |
| 1126 | # TODO: if mode="a", consider overriding the existing variable |
| 1127 | # metadata. This would need some case work properly with region |
| 1128 | # and append_dim. |
| 1129 | if self._write_empty is not None: |
| 1130 | # Write to zarr_group.chunk_store instead of zarr_group.store |
| 1131 | # See https://github.com/pydata/xarray/pull/8326#discussion_r1365311316 for a longer explanation |
| 1132 | # The open_consolidated() enforces a mode of r or r+ |
| 1133 | # (and to_zarr with region provided enforces a read mode of r+), |
| 1134 | # and this function makes sure the resulting Group has a store of type ConsolidatedMetadataStore |
| 1135 | # and a 'normal Store subtype for chunk_store. |
| 1136 | # The exact type depends on if a local path was used, or a URL of some sort, |
| 1137 | # but the point is that it's not a read-only ConsolidatedMetadataStore. |
| 1138 | # It is safe to write chunk data to the chunk_store because no metadata would be changed by |
| 1139 | # to_zarr with the region parameter: |
| 1140 | # - Because the write mode is enforced to be r+, no new variables can be added to the store |
| 1141 | # (this is also checked and enforced in xarray.backends.api.py::to_zarr()). |
| 1142 | # - Existing variables already have their attrs included in the consolidated metadata file. |
| 1143 | # - The size of dimensions can not be expanded, that would require a call using `append_dim` |
| 1144 | # which is mutually exclusive with `region` |
| 1145 | empty: dict[str, bool] | dict[str, dict[str, bool]] |
| 1146 | if _zarr_v3(): |
| 1147 | empty = dict(config={"write_empty_chunks": self._write_empty}) |
| 1148 | else: |
| 1149 | empty = dict(write_empty_chunks=self._write_empty) |
| 1150 | |
| 1151 | zarr_array = zarr.open( |
| 1152 | store=( |
| 1153 | self.zarr_group.store if _zarr_v3() else self.zarr_group.chunk_store |
| 1154 | ), |
| 1155 | # TODO: see if zarr should normalize these strings. |
| 1156 | path="/".join([self.zarr_group.name.rstrip("/"), name]).lstrip("/"), |
| 1157 | **empty, |
| 1158 | ) |
| 1159 | else: |
| 1160 | zarr_array = self.zarr_group[name] |
| 1161 | |
| 1162 | return cast(ZarrArray, zarr_array) |
| 1163 | |
| 1164 | def _create_new_array( |
| 1165 | self, *, name, shape, dtype, fill_value, encoding, attrs |