@@ -157,6 +157,34 @@ def check_alignment(
157
157
check_alignment (child_path , child_ds , base_ds , child .children )
158
158
159
159
160
+ def _deduplicate_inherited_coordinates (child : DataTree , parent : DataTree ) -> None :
161
+ # This method removes repeated indexes (and corresponding coordinates)
162
+ # that are repeated between a DataTree and its parents.
163
+ #
164
+ # TODO(shoyer): Decide how to handle repeated coordinates *without* an
165
+ # index. Should these be allowed, in which case we probably want to
166
+ # exclude them from inheritance, or should they be automatically
167
+ # dropped?
168
+ # https://github.com/pydata/xarray/issues/9475#issuecomment-2357004264
169
+ removed_something = False
170
+ for name in parent ._indexes :
171
+ if name in child ._node_indexes :
172
+ # Indexes on a Dataset always have a corresponding coordinate.
173
+ # We already verified that these coordinates match in the
174
+ # check_alignment() call from _pre_attach().
175
+ del child ._node_indexes [name ]
176
+ del child ._node_coord_variables [name ]
177
+ removed_something = True
178
+
179
+ if removed_something :
180
+ child ._node_dims = calculate_dimensions (
181
+ child ._data_variables | child ._node_coord_variables
182
+ )
183
+
184
+ for grandchild in child ._children .values ():
185
+ _deduplicate_inherited_coordinates (grandchild , child )
186
+
187
+
160
188
def _check_for_slashes_in_names (variables : Iterable [Hashable ]) -> None :
161
189
offending_variable_names = [
162
190
name for name in variables if isinstance (name , str ) and "/" in name
@@ -375,7 +403,7 @@ def map( # type: ignore[override]
375
403
376
404
377
405
class DataTree (
378
- NamedNode ,
406
+ NamedNode [ "DataTree" ] ,
379
407
MappedDatasetMethodsMixin ,
380
408
MappedDataWithCoords ,
381
409
DataTreeArithmeticMixin ,
@@ -486,6 +514,7 @@ def _pre_attach(self: DataTree, parent: DataTree, name: str) -> None:
486
514
node_ds = self .to_dataset (inherited = False )
487
515
parent_ds = parent ._to_dataset_view (rebuild_dims = False , inherited = True )
488
516
check_alignment (path , node_ds , parent_ds , self .children )
517
+ _deduplicate_inherited_coordinates (self , parent )
489
518
490
519
@property
491
520
def _coord_variables (self ) -> ChainMap [Hashable , Variable ]:
@@ -1353,7 +1382,7 @@ def map_over_subtree(
1353
1382
func : Callable ,
1354
1383
* args : Iterable [Any ],
1355
1384
** kwargs : Any ,
1356
- ) -> DataTree | tuple [DataTree ]:
1385
+ ) -> DataTree | tuple [DataTree , ... ]:
1357
1386
"""
1358
1387
Apply a function to every dataset in this subtree, returning a new tree which stores the results.
1359
1388
0 commit comments