@@ -157,6 +157,34 @@ def check_alignment(
157157 check_alignment (child_path , child_ds , base_ds , child .children )
158158
159159
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+
160188def _check_for_slashes_in_names (variables : Iterable [Hashable ]) -> None :
161189 offending_variable_names = [
162190 name for name in variables if isinstance (name , str ) and "/" in name
@@ -375,7 +403,7 @@ def map( # type: ignore[override]
375403
376404
377405class DataTree (
378- NamedNode ,
406+ NamedNode [ "DataTree" ] ,
379407 MappedDatasetMethodsMixin ,
380408 MappedDataWithCoords ,
381409 DataTreeArithmeticMixin ,
@@ -486,6 +514,7 @@ def _pre_attach(self: DataTree, parent: DataTree, name: str) -> None:
486514 node_ds = self .to_dataset (inherited = False )
487515 parent_ds = parent ._to_dataset_view (rebuild_dims = False , inherited = True )
488516 check_alignment (path , node_ds , parent_ds , self .children )
517+ _deduplicate_inherited_coordinates (self , parent )
489518
490519 @property
491520 def _coord_variables (self ) -> ChainMap [Hashable , Variable ]:
@@ -1353,7 +1382,7 @@ def map_over_subtree(
13531382 func : Callable ,
13541383 * args : Iterable [Any ],
13551384 ** kwargs : Any ,
1356- ) -> DataTree | tuple [DataTree ]:
1385+ ) -> DataTree | tuple [DataTree , ... ]:
13571386 """
13581387 Apply a function to every dataset in this subtree, returning a new tree which stores the results.
13591388
0 commit comments