Skip to content
forked from pydata/xarray

Commit fac2c89

Browse files
authored
Rename DataTree's "ds" and "data" to "dataset" (pydata#9476)
* Rename DataTree's "ds" and "data" to "dataset" .ds is kept around as a soft-deprecated alias to facilitate the transition from xarray-contrib/datatree, though I verified that all tests pass without it. * fix data= usage in test_formatting_html.py * fix formatting test
1 parent a6bacfe commit fac2c89

8 files changed

+95
-92
lines changed

xarray/backends/zarr.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ def open_datatree(
12621262
ds = open_dataset(
12631263
filename_or_obj, store=store, group=path_group, engine="zarr", **kwargs
12641264
)
1265-
new_node: DataTree = DataTree(name=NodePath(path_group).name, data=ds)
1265+
new_node = DataTree(name=NodePath(path_group).name, dataset=ds)
12661266
tree_root._set_item(
12671267
path_group,
12681268
new_node,

xarray/core/datatree.py

+35-31
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ class DataTree(
417417

418418
def __init__(
419419
self,
420-
data: Dataset | None = None,
420+
dataset: Dataset | None = None,
421421
children: Mapping[str, DataTree] | None = None,
422422
name: str | None = None,
423423
):
@@ -430,12 +430,12 @@ def __init__(
430430
431431
Parameters
432432
----------
433-
data : Dataset, optional
434-
Data to store under the .ds attribute of this node.
433+
dataset : Dataset, optional
434+
Data to store directly at this node.
435435
children : Mapping[str, DataTree], optional
436-
Any child nodes of this node. Default is None.
436+
Any child nodes of this node.
437437
name : str, optional
438-
Name for this node of the tree. Default is None.
438+
Name for this node of the tree.
439439
440440
Returns
441441
-------
@@ -449,24 +449,24 @@ def __init__(
449449
children = {}
450450

451451
super().__init__(name=name)
452-
self._set_node_data(_to_new_dataset(data))
452+
self._set_node_data(_to_new_dataset(dataset))
453453

454454
# shallow copy to avoid modifying arguments in-place (see GH issue #9196)
455455
self.children = {name: child.copy() for name, child in children.items()}
456456

457-
def _set_node_data(self, ds: Dataset):
458-
data_vars, coord_vars = _collect_data_and_coord_variables(ds)
457+
def _set_node_data(self, dataset: Dataset):
458+
data_vars, coord_vars = _collect_data_and_coord_variables(dataset)
459459
self._data_variables = data_vars
460460
self._node_coord_variables = coord_vars
461-
self._node_dims = ds._dims
462-
self._node_indexes = ds._indexes
463-
self._encoding = ds._encoding
464-
self._attrs = ds._attrs
465-
self._close = ds._close
461+
self._node_dims = dataset._dims
462+
self._node_indexes = dataset._indexes
463+
self._encoding = dataset._encoding
464+
self._attrs = dataset._attrs
465+
self._close = dataset._close
466466

467467
def _pre_attach(self: DataTree, parent: DataTree, name: str) -> None:
468468
super()._pre_attach(parent, name)
469-
if name in parent.ds.variables:
469+
if name in parent.dataset.variables:
470470
raise KeyError(
471471
f"parent {parent.name} already contains a variable named {name}"
472472
)
@@ -534,7 +534,7 @@ def _to_dataset_view(self, rebuild_dims: bool, inherited: bool) -> DatasetView:
534534
)
535535

536536
@property
537-
def ds(self) -> DatasetView:
537+
def dataset(self) -> DatasetView:
538538
"""
539539
An immutable Dataset-like view onto the data in this node.
540540
@@ -549,11 +549,15 @@ def ds(self) -> DatasetView:
549549
"""
550550
return self._to_dataset_view(rebuild_dims=True, inherited=True)
551551

552-
@ds.setter
553-
def ds(self, data: Dataset | None = None) -> None:
552+
@dataset.setter
553+
def dataset(self, data: Dataset | None = None) -> None:
554554
ds = _to_new_dataset(data)
555555
self._replace_node(ds)
556556

557+
# soft-deprecated alias, to facilitate the transition from
558+
# xarray-contrib/datatree
559+
ds = dataset
560+
557561
def to_dataset(self, inherited: bool = True) -> Dataset:
558562
"""
559563
Return the data in this node as a new xarray.Dataset object.
@@ -566,7 +570,7 @@ def to_dataset(self, inherited: bool = True) -> Dataset:
566570
567571
See Also
568572
--------
569-
DataTree.ds
573+
DataTree.dataset
570574
"""
571575
coord_vars = self._coord_variables if inherited else self._node_coord_variables
572576
variables = dict(self._data_variables)
@@ -845,8 +849,8 @@ def get( # type: ignore[override]
845849
"""
846850
if key in self.children:
847851
return self.children[key]
848-
elif key in self.ds:
849-
return self.ds[key]
852+
elif key in self.dataset:
853+
return self.dataset[key]
850854
else:
851855
return default
852856

@@ -1114,7 +1118,7 @@ def from_dict(
11141118
if isinstance(root_data, DataTree):
11151119
obj = root_data.copy()
11161120
elif root_data is None or isinstance(root_data, Dataset):
1117-
obj = cls(name=name, data=root_data, children=None)
1121+
obj = cls(name=name, dataset=root_data, children=None)
11181122
else:
11191123
raise TypeError(
11201124
f'root node data (at "/") must be a Dataset or DataTree, got {type(root_data)}'
@@ -1133,7 +1137,7 @@ def depth(item) -> int:
11331137
if isinstance(data, DataTree):
11341138
new_node = data.copy()
11351139
elif isinstance(data, Dataset) or data is None:
1136-
new_node = cls(name=node_name, data=data)
1140+
new_node = cls(name=node_name, dataset=data)
11371141
else:
11381142
raise TypeError(f"invalid values: {data}")
11391143
obj._set_item(
@@ -1264,7 +1268,7 @@ def equals(self, other: DataTree, from_root: bool = True) -> bool:
12641268

12651269
return all(
12661270
[
1267-
node.ds.equals(other_node.ds)
1271+
node.dataset.equals(other_node.dataset)
12681272
for node, other_node in zip(self.subtree, other.subtree, strict=True)
12691273
]
12701274
)
@@ -1294,7 +1298,7 @@ def identical(self, other: DataTree, from_root=True) -> bool:
12941298
return False
12951299

12961300
return all(
1297-
node.ds.identical(other_node.ds)
1301+
node.dataset.identical(other_node.dataset)
12981302
for node, other_node in zip(self.subtree, other.subtree, strict=True)
12991303
)
13001304

@@ -1321,7 +1325,7 @@ def filter(self: DataTree, filterfunc: Callable[[DataTree], bool]) -> DataTree:
13211325
map_over_subtree
13221326
"""
13231327
filtered_nodes = {
1324-
node.path: node.ds for node in self.subtree if filterfunc(node)
1328+
node.path: node.dataset for node in self.subtree if filterfunc(node)
13251329
}
13261330
return DataTree.from_dict(filtered_nodes, name=self.root.name)
13271331

@@ -1365,7 +1369,7 @@ def match(self, pattern: str) -> DataTree:
13651369
└── Group: /b/B
13661370
"""
13671371
matching_nodes = {
1368-
node.path: node.ds
1372+
node.path: node.dataset
13691373
for node in self.subtree
13701374
if NodePath(node.path).match(pattern)
13711375
}
@@ -1389,7 +1393,7 @@ def map_over_subtree(
13891393
----------
13901394
func : callable
13911395
Function to apply to datasets with signature:
1392-
`func(node.ds, *args, **kwargs) -> Dataset`.
1396+
`func(node.dataset, *args, **kwargs) -> Dataset`.
13931397
13941398
Function will not be applied to any nodes without datasets.
13951399
*args : tuple, optional
@@ -1420,7 +1424,7 @@ def map_over_subtree_inplace(
14201424
----------
14211425
func : callable
14221426
Function to apply to datasets with signature:
1423-
`func(node.ds, *args, **kwargs) -> Dataset`.
1427+
`func(node.dataset, *args, **kwargs) -> Dataset`.
14241428
14251429
Function will not be applied to any nodes without datasets,
14261430
*args : tuple, optional
@@ -1433,7 +1437,7 @@ def map_over_subtree_inplace(
14331437

14341438
for node in self.subtree:
14351439
if node.has_data:
1436-
node.ds = func(node.ds, *args, **kwargs)
1440+
node.dataset = func(node.dataset, *args, **kwargs)
14371441

14381442
def pipe(
14391443
self, func: Callable | tuple[Callable, str], *args: Any, **kwargs: Any
@@ -1499,7 +1503,7 @@ def render(self):
14991503
"""Print tree structure, including any data stored at each node."""
15001504
for pre, fill, node in RenderDataTree(self):
15011505
print(f"{pre}DataTree('{self.name}')")
1502-
for ds_line in repr(node.ds)[1:]:
1506+
for ds_line in repr(node.dataset)[1:]:
15031507
print(f"{fill}{ds_line}")
15041508

15051509
def merge(self, datatree: DataTree) -> DataTree:
@@ -1513,7 +1517,7 @@ def merge_child_nodes(self, *paths, new_path: T_Path) -> DataTree:
15131517
# TODO some kind of .collapse() or .flatten() method to merge a subtree
15141518

15151519
def to_dataarray(self) -> DataArray:
1516-
return self.ds.to_dataarray()
1520+
return self.dataset.to_dataarray()
15171521

15181522
@property
15191523
def groups(self):

xarray/core/datatree_mapping.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ def map_over_subtree(func: Callable) -> Callable:
9999
Function will not be applied to any nodes without datasets.
100100
*args : tuple, optional
101101
Positional arguments passed on to `func`. If DataTrees any data-containing nodes will be converted to Datasets
102-
via `.ds`.
102+
via `.dataset`.
103103
**kwargs : Any
104104
Keyword arguments passed on to `func`. If DataTrees any data-containing nodes will be converted to Datasets
105-
via `.ds`.
105+
via `.dataset`.
106106
107107
Returns
108108
-------
@@ -160,13 +160,14 @@ def _map_over_subtree(*args, **kwargs) -> DataTree | tuple[DataTree, ...]:
160160
strict=False,
161161
):
162162
node_args_as_datasetviews = [
163-
a.ds if isinstance(a, DataTree) else a for a in all_node_args[:n_args]
163+
a.dataset if isinstance(a, DataTree) else a
164+
for a in all_node_args[:n_args]
164165
]
165166
node_kwargs_as_datasetviews = dict(
166167
zip(
167168
[k for k in kwargs_as_tree_length_iterables.keys()],
168169
[
169-
v.ds if isinstance(v, DataTree) else v
170+
v.dataset if isinstance(v, DataTree) else v
170171
for v in all_node_args[n_args:]
171172
],
172173
strict=True,
@@ -183,7 +184,7 @@ def _map_over_subtree(*args, **kwargs) -> DataTree | tuple[DataTree, ...]:
183184
)
184185
elif node_of_first_tree.has_attrs:
185186
# propagate attrs
186-
results = node_of_first_tree.ds
187+
results = node_of_first_tree.dataset
187188
else:
188189
# nothing to propagate so use fastpath to create empty node in new tree
189190
results = None

xarray/core/formatting.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ def diff_nodewise_summary(a: DataTree, b: DataTree, compat):
10381038

10391039
summary = []
10401040
for node_a, node_b in zip(a.subtree, b.subtree, strict=True):
1041-
a_ds, b_ds = node_a.ds, node_b.ds
1041+
a_ds, b_ds = node_a.dataset, node_b.dataset
10421042

10431043
if not a_ds._all_compat(b_ds, compat):
10441044
dataset_diff = diff_dataset_repr(a_ds, b_ds, compat_str)

xarray/tests/test_backends_datatree.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_netcdf_encoding(self, tmpdir, simple_datatree):
5656

5757
# add compression
5858
comp = dict(zlib=True, complevel=9)
59-
enc = {"/set2": {var: comp for var in original_dt["/set2"].ds.data_vars}}
59+
enc = {"/set2": {var: comp for var in original_dt["/set2"].dataset.data_vars}}
6060

6161
original_dt.to_netcdf(filepath, encoding=enc, engine=self.engine)
6262
roundtrip_dt = open_datatree(filepath, engine=self.engine)
@@ -246,7 +246,7 @@ def test_zarr_encoding(self, tmpdir, simple_datatree):
246246
original_dt = simple_datatree
247247

248248
comp = {"compressor": zarr.Blosc(cname="zstd", clevel=3, shuffle=2)}
249-
enc = {"/set2": {var: comp for var in original_dt["/set2"].ds.data_vars}}
249+
enc = {"/set2": {var: comp for var in original_dt["/set2"].dataset.data_vars}}
250250
original_dt.to_zarr(filepath, encoding=enc)
251251
roundtrip_dt = open_datatree(filepath, engine="zarr")
252252

0 commit comments

Comments
 (0)