From 7c6fa70e6e1c929ea6424e4bb439b9d182245406 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 4 Jan 2023 15:20:12 -0500 Subject: [PATCH 01/20] list datatree in public API --- doc/api.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/api.rst b/doc/api.rst index 0d56fc73997..a253c53b07b 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -1133,6 +1133,20 @@ used filetypes in the xarray universe. backends.StoreBackendEntrypoint backends.ZarrBackendEntrypoint +DataTree +======== + +Experimental API for handling nested groups of data. +Requires the `xarray-datatree package `_ to be installed. +See the `datatree documentation `_ for details. + +.. autosummary:: + :toctree: generated/ + + DataTree + open_datatree + register_datatree_accessor + Deprecated / Pending Deprecation ================================ From 5ef43bebc001ebc601c2691333478e32d19ee7c6 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 4 Jan 2023 15:25:20 -0500 Subject: [PATCH 02/20] attempt to import datatree API on xarray import --- xarray/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xarray/__init__.py b/xarray/__init__.py index d064502c20b..a4517ab4679 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -52,6 +52,12 @@ # Disable minimum version checks on downstream libraries. __version__ = "999" +try: + from datatree import DataTree, open_datatree, register_datatree_accessor +except ImportError: + ... + + # A hardcoded __all__ variable is necessary to appease # `mypy --strict` running in projects that import xarray. __all__ = ( From d1847641483c72788141dbce0df9334e41a1c24e Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 4 Jan 2023 15:26:07 -0500 Subject: [PATCH 03/20] incorporate datatree links into io docs on groups --- doc/user-guide/io.rst | 48 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/doc/user-guide/io.rst b/doc/user-guide/io.rst index f2d3c6cc9d9..404911dda2f 100644 --- a/doc/user-guide/io.rst +++ b/doc/user-guide/io.rst @@ -156,6 +156,9 @@ to the original netCDF file, regardless if they exist in the original dataset. Groups ~~~~~~ +Single groups as datasets +......................... + NetCDF groups are not supported as part of the :py:class:`Dataset` data model. Instead, groups can be loaded individually as Dataset objects. To do so, pass a ``group`` keyword argument to the @@ -228,10 +231,34 @@ Either of these groups can be loaded from the file as an independent :py:class:` Data variables: b int64 ... -.. note:: +.. _io.netcdf_datatree_groups: + +Multiple Groups as a DataTree +............................. + +For native handling of multiple groups with xarray, including I/O, you might be interested in the experimental +`xarray-datatree `_ package. +If installed, this package's API can be imported directly from xarray, i.e. ``from xarray import DataTree``. + +Whilst netCDF groups can only be loaded individually as Dataset objects, a whole file of many nested groups can be loaded +as a single :py:class:`DataTree` object. +To open a whole netCDF file as a tree of groups use the :py:func:`open_datatree()` function. +To save a DataTree object as a netCDF file containing many groups, use the :py:meth:`DataTree.to_netcdf()`` method. + +.. _netcdf.group.warning: + +.. warning:: + ``DataTree`` objects do not follow the exact same data model as netCDF files, which means that perfect round-tripping + is not always possible. + + In particular in the netCDF data model dimensions are entities that can exist regardless of whether any variable possesses them. + This is in contrast to `xarray's data model `_ + (and hence `datatree's data model `_) in which the dimensions of a (Dataset/Tree) + object are simply the set of dimensions present across all variables in that dataset. - For native handling of multiple groups with xarray, including I/O, you might be interested in the experimental - `xarray-datatree `_ package. + This means that if a netCDF file contains dimensions but no variables which possess those dimensions, + these dimensions will not be present when that file is opened as a DataTree object. + Saving this DataTree object to file will therefore not preserve these "unused" dimensions. .. _io.encoding: @@ -633,6 +660,21 @@ To read back a zarr dataset that has been created this way, we use the ds_zarr = xr.open_zarr("path/to/directory.zarr") ds_zarr +Groups +~~~~~~ + +Like for netCDF, zarr groups can either be opened as individual :py:class:`Dataset` objects using the ``group`` keyword argument to :py:func:`open_dataset`, +or alternatively nested groups in zarr stores can be represented by loading the store as a :py:class:`DataTree` object. +(The latter option requires that you have the `xarray-datatree `_ package installed.) + +To open a whole zarr store as a tree of groups use the :py:func:`open_datatree()` function. +To save a DataTree object as a zarr store containing many groups, use the :py:meth:`DataTree.to_zarr()` method. + +.. note:: + Note that perfect round-tripping should always be possible with a zarr store (:ref:`unlike for netCDF files`), + as zarr does not support "unused" dimensions. + + Cloud Storage Buckets ~~~~~~~~~~~~~~~~~~~~~ From d2e8ec3e30a0f7ee2b657121e59aecdaa20d7b69 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Thu, 12 Jan 2023 16:11:07 -0500 Subject: [PATCH 04/20] add Dataset.to_datatree() method --- xarray/core/dataset.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 3d4bf0a9a20..792509e1df4 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -6117,6 +6117,45 @@ def to_array( return DataArray._construct_direct(variable, coords, name, indexes) + def to_datatree(self, name: str | None = None): + """ + Convert this dataset into a datatree.DataTree. + + WARNING: The DataTree structure is considered experimental, + and the API is less solidified than for other xarray features. + + The returned tree will only consist of a single node. + That node will contain a copy of the dataset's data, + meaning all variables, coordinates, dimensions and attributes. + + Requires the xarray-datatree package to be installed. + Find it at https://github.com/xarray-contrib/datatree. + + Parameters + ---------- + name: str, optional + The name of the datatree node created. + + Returns + ------- + dt : DataTree + A single-node datatree object, containing the information from this dataset. + + See Also + -------- + datatree.DataTree + """ + + try: + from datatree import DataTree + except ImportError: + raise ImportError( + "Could not import the datatree package. " + "Find it at https://github.com/xarray-contrib/datatree" + ) + + return DataTree(data=self, name=name) + def _normalize_dim_order( self, dim_order: Sequence[Hashable] | None = None ) -> dict[Hashable, int]: From c5b8d1010f8cae828540ff78495aa8ef7a140198 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 18:46:49 -0500 Subject: [PATCH 05/20] add test that DataTree class can be imported --- xarray/tests/__init__.py | 1 + xarray/tests/test_datatree.py | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 xarray/tests/test_datatree.py diff --git a/xarray/tests/__init__.py b/xarray/tests/__init__.py index 6970a34b63d..0b8073c5d12 100644 --- a/xarray/tests/__init__.py +++ b/xarray/tests/__init__.py @@ -83,6 +83,7 @@ def _importorskip( has_pint, requires_pint = _importorskip("pint") has_numexpr, requires_numexpr = _importorskip("numexpr") has_flox, requires_flox = _importorskip("flox") +has_datatree, requires_datatree = _importorskip("datatree") # some special cases diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py new file mode 100644 index 00000000000..43220c3064c --- /dev/null +++ b/xarray/tests/test_datatree.py @@ -0,0 +1,10 @@ +from xarray.tests import requires_datatree + + +@requires_datatree +def test_import_datatree(): + """Just test importing datatree package from xarray-contrib repo""" + from xarray import DataTree, open_datatree + + DataTree() + \ No newline at end of file From 62b5e276a778c5e66e1ddd8e58d37638ece41819 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 18:51:53 -0500 Subject: [PATCH 06/20] add to every CI environment that also has flox --- ci/install-upstream-wheels.sh | 2 ++ ci/requirements/all-but-dask.yml | 1 + ci/requirements/environment-py311.yml | 1 + ci/requirements/environment-windows-py311.yml | 1 + ci/requirements/environment-windows.yml | 1 + ci/requirements/environment.yml | 1 + 6 files changed, 7 insertions(+) diff --git a/ci/install-upstream-wheels.sh b/ci/install-upstream-wheels.sh index 62bf08b366f..65ba2878ae4 100755 --- a/ci/install-upstream-wheels.sh +++ b/ci/install-upstream-wheels.sh @@ -20,6 +20,7 @@ conda uninstall -y --force \ bottleneck \ sparse \ flox \ + datatree \ h5netcdf \ xarray # to limit the runtime of Upstream CI @@ -47,5 +48,6 @@ python -m pip install \ git+https://github.com/intake/filesystem_spec \ git+https://github.com/SciTools/nc-time-axis \ git+https://github.com/xarray-contrib/flox \ + git+https://github.com/xarray-contrib/xarray-datatree \ git+https://github.com/h5netcdf/h5netcdf python -m pip install pytest-timeout diff --git a/ci/requirements/all-but-dask.yml b/ci/requirements/all-but-dask.yml index ce819640c76..373aa4e0f73 100644 --- a/ci/requirements/all-but-dask.yml +++ b/ci/requirements/all-but-dask.yml @@ -41,4 +41,5 @@ dependencies: - sparse - toolz - typing_extensions + - xarray-datatree - zarr diff --git a/ci/requirements/environment-py311.yml b/ci/requirements/environment-py311.yml index e23fa44c683..8f5852e03d3 100644 --- a/ci/requirements/environment-py311.yml +++ b/ci/requirements/environment-py311.yml @@ -45,4 +45,5 @@ dependencies: # - sparse - toolz - typing_extensions + - xarray-datatree - zarr diff --git a/ci/requirements/environment-windows-py311.yml b/ci/requirements/environment-windows-py311.yml index 3fc207dc609..3c77fa38b1d 100644 --- a/ci/requirements/environment-windows-py311.yml +++ b/ci/requirements/environment-windows-py311.yml @@ -41,4 +41,5 @@ dependencies: # - sparse - toolz - typing_extensions + - xarray-datatree - zarr diff --git a/ci/requirements/environment-windows.yml b/ci/requirements/environment-windows.yml index 0941af474f7..4a33c20ca2a 100644 --- a/ci/requirements/environment-windows.yml +++ b/ci/requirements/environment-windows.yml @@ -41,4 +41,5 @@ dependencies: - sparse - toolz - typing_extensions + - xarray-datatree - zarr diff --git a/ci/requirements/environment.yml b/ci/requirements/environment.yml index e87e69138ee..37f758a018a 100644 --- a/ci/requirements/environment.yml +++ b/ci/requirements/environment.yml @@ -45,4 +45,5 @@ dependencies: - sparse - toolz - typing_extensions + - xarray-datatree - zarr From ffa53c470980623bff5fef9b1c67fda126b46edd Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 19:06:44 -0500 Subject: [PATCH 07/20] also check we can import accessor --- xarray/tests/test_datatree.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index 43220c3064c..8144ca68857 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -4,7 +4,6 @@ @requires_datatree def test_import_datatree(): """Just test importing datatree package from xarray-contrib repo""" - from xarray import DataTree, open_datatree + from xarray import DataTree, open_datatree, register_datatree_accessor DataTree() - \ No newline at end of file From a8f752df39126beb129fff0cd2632e945cfbe272 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 19:28:50 -0500 Subject: [PATCH 08/20] whatsnew --- doc/whats-new.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index b0f6a07841b..ba8676e4f89 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -23,6 +23,15 @@ v2023.01.1 (unreleased) New Features ~~~~~~~~~~~~ +- Allow importing the prototype :py:class:`DataTree` class (as well as the accompanying :py:func:`open_datatree()` and :py:func:`register_datatree_accessor` functions). + Currently ``from xarray import DataTree`` disguises an import from a separate package ``xarray-contrib/xarray-datatree``. + Importing these features will raise an ``ImportError`` unless the datatree package is installed. + Full integration of the :py:class:`DataTree` class in xarray is planned in the future (see our development roadmap), + but for now is proceeding on a provisional basis, and as such the API is still experimental and subject to change without notice. + In the meantime, you are encouraged to try using these features, and please let us know about your experiences! + (:issue:`4118`, :pull:`7418`) + By `Tom Nicholas `_. + Breaking changes ~~~~~~~~~~~~~~~~ From 3d3c29fb393e0bcc9a0d9980aa19978baff60ecf Mon Sep 17 00:00:00 2001 From: Tom Nicholas Date: Tue, 31 Jan 2023 19:30:11 -0500 Subject: [PATCH 09/20] Update to_node docstring Co-authored-by: Joe Hamman --- xarray/core/dataset.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 5c129e893ea..c5fd8059893 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -6114,15 +6114,15 @@ def to_datatree(self, name: str | None = None): """ Convert this dataset into a datatree.DataTree. - WARNING: The DataTree structure is considered experimental, - and the API is less solidified than for other xarray features. - - The returned tree will only consist of a single node. - That node will contain a copy of the dataset's data, - meaning all variables, coordinates, dimensions and attributes. - - Requires the xarray-datatree package to be installed. - Find it at https://github.com/xarray-contrib/datatree. + .. warning:: The DataTree structure is considered experimental, + and the API is less solidified than for other xarray features. + + The returned tree will only consist of a single node. + That node will contain a copy of the dataset's data, + meaning all variables, coordinates, dimensions and attributes. + + Requires the xarray-datatree package to be installed. + Find it at https://github.com/xarray-contrib/datatree. Parameters ---------- From 95d76e6604dd3d735cc7fd1cb50d8e7e1afc1dc7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 00:31:49 +0000 Subject: [PATCH 10/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- xarray/__init__.py | 2 +- xarray/core/dataset.py | 4 ++-- xarray/tests/test_datatree.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index a4517ab4679..0946cfea04a 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -53,7 +53,7 @@ __version__ = "999" try: - from datatree import DataTree, open_datatree, register_datatree_accessor + pass except ImportError: ... diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index e173307825f..ae04fd95b58 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -6122,11 +6122,11 @@ def to_datatree(self, name: str | None = None): .. warning:: The DataTree structure is considered experimental, and the API is less solidified than for other xarray features. - + The returned tree will only consist of a single node. That node will contain a copy of the dataset's data, meaning all variables, coordinates, dimensions and attributes. - + Requires the xarray-datatree package to be installed. Find it at https://github.com/xarray-contrib/datatree. diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index 8144ca68857..578df8f742c 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -4,6 +4,6 @@ @requires_datatree def test_import_datatree(): """Just test importing datatree package from xarray-contrib repo""" - from xarray import DataTree, open_datatree, register_datatree_accessor + from xarray import DataTree DataTree() From caafe90a29b0dc49ba9cca5ee12dc233a0a7462f Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 20:00:13 -0500 Subject: [PATCH 11/20] test .to_datatree method --- xarray/core/dataarray.py | 42 +++++++++++++++++++++++++++++++++++ xarray/core/dataset.py | 6 ++--- xarray/core/types.py | 5 +++++ xarray/tests/test_datatree.py | 22 ++++++++++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 8fefef5aff7..6ad6b0f3e54 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -3656,6 +3656,48 @@ def reduce( var = self.variable.reduce(func, dim, axis, keep_attrs, keepdims, **kwargs) return self._replace_maybe_drop_dims(var) + def to_datatree(self, node_name: str | None = None, name: str | None = None): + """ + Convert this dataarray into a datatree.DataTree. + + WARNING: The DataTree structure is considered experimental, + and the API is less solidified than for other xarray features. + + The returned tree will only consist of a single node. + That node will contain a copy of the dataarray's data, + meaning including its coordinates, dimensions and attributes. + + Requires the xarray-datatree package to be installed. + Find it at https://github.com/xarray-contrib/datatree. + + Parameters + ---------- + node_name: str, optional + The name of the datatree node created. + name: str, optional + Name to substitute for this array's name. + + Returns + ------- + dt : DataTree + A single-node datatree object, containing the information from this dataarray. + + See Also + -------- + datatree.DataTree + """ + + try: + from datatree import DataTree + except ImportError: + raise ImportError( + "Could not import the datatree package. " + "Find it at https://github.com/xarray-contrib/datatree" + ) + + ds = self.to_dataset(name=name) + return DataTree(data=ds, name=node_name) + def to_pandas(self) -> DataArray | pd.Series | pd.DataFrame: """Convert this array into a pandas object with the same shape. diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 5c129e893ea..ef74d95bce2 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -6110,7 +6110,7 @@ def to_array( return DataArray._construct_direct(variable, coords, name, indexes) - def to_datatree(self, name: str | None = None): + def to_datatree(self, node_name: str | None = None): """ Convert this dataset into a datatree.DataTree. @@ -6126,7 +6126,7 @@ def to_datatree(self, name: str | None = None): Parameters ---------- - name: str, optional + node_name: str, optional The name of the datatree node created. Returns @@ -6147,7 +6147,7 @@ def to_datatree(self, name: str | None = None): "Find it at https://github.com/xarray-contrib/datatree" ) - return DataTree(data=self, name=name) + return DataTree(data=self, name=node_name) def _normalize_dim_order( self, dim_order: Sequence[Hashable] | None = None diff --git a/xarray/core/types.py b/xarray/core/types.py index fc3c6712be2..edc71dcdba5 100644 --- a/xarray/core/types.py +++ b/xarray/core/types.py @@ -28,6 +28,11 @@ from xarray.core.indexes import Index from xarray.core.variable import Variable + try: + from datatree import DataTree as T_DataTree + except ImportError: + T_DataTree = Any + try: from dask.array import Array as DaskArray except ImportError: diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index 8144ca68857..99342865149 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -1,3 +1,7 @@ +from xarray import Dataset + +import xarray.testing as xrt + from xarray.tests import requires_datatree @@ -7,3 +11,21 @@ def test_import_datatree(): from xarray import DataTree, open_datatree, register_datatree_accessor DataTree() + +@requires_datatree +def test_to_datatree(): + from xarray import DataTree + + ds = Dataset({"a": ("x", [1, 2, 3])}) + dt = ds.to_datatree(node_name="group1") + + assert isinstance(dt, DataTree) + assert dt.name == "group1" + xrt.assert_identical(dt.to_dataset(), ds) + + da = ds['a'] + dt = da.to_datatree(node_name="group1") + + assert isinstance(dt, DataTree) + assert dt.name == "group1" + xrt.assert_identical(dt['a'], da) From 91c6ee15a384cf7f6253f70690d7a446ede1df21 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 01:01:32 +0000 Subject: [PATCH 12/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- xarray/tests/test_datatree.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index f7ab9a67eab..66d2ac3420d 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -1,7 +1,5 @@ -from xarray import Dataset - import xarray.testing as xrt - +from xarray import Dataset from xarray.tests import requires_datatree @@ -12,6 +10,7 @@ def test_import_datatree(): DataTree() + @requires_datatree def test_to_datatree(): from xarray import DataTree @@ -23,9 +22,9 @@ def test_to_datatree(): assert dt.name == "group1" xrt.assert_identical(dt.to_dataset(), ds) - da = ds['a'] + da = ds["a"] dt = da.to_datatree(node_name="group1") assert isinstance(dt, DataTree) assert dt.name == "group1" - xrt.assert_identical(dt['a'], da) + xrt.assert_identical(dt["a"], da) From bc6a5381ac89ed910e9725322838c8fa456a2841 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 20:18:54 -0500 Subject: [PATCH 13/20] fix datatree import --- xarray/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index 0946cfea04a..a4517ab4679 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -53,7 +53,7 @@ __version__ = "999" try: - pass + from datatree import DataTree, open_datatree, register_datatree_accessor except ImportError: ... From 3baf79ed9e6d37e5d869973d5c74372a8bf8c760 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 01:19:30 +0000 Subject: [PATCH 14/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- xarray/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index a4517ab4679..0946cfea04a 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -53,7 +53,7 @@ __version__ = "999" try: - from datatree import DataTree, open_datatree, register_datatree_accessor + pass except ImportError: ... From 667d5cdbb06b1d872aea2905bf790e8be97a8de4 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 23:09:54 -0500 Subject: [PATCH 15/20] protect my import from the exacting ruff linter --- xarray/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index a4517ab4679..776065fe76c 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -53,7 +53,7 @@ __version__ = "999" try: - from datatree import DataTree, open_datatree, register_datatree_accessor + from datatree import DataTree # noqa except ImportError: ... From d23105565dbca6b0b924b6d1e1da33a5797347a6 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Tue, 31 Jan 2023 23:29:32 -0500 Subject: [PATCH 16/20] try installing datatree from main --- ci/requirements/environment.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/requirements/environment.yml b/ci/requirements/environment.yml index 37f758a018a..f59e0934551 100644 --- a/ci/requirements/environment.yml +++ b/ci/requirements/environment.yml @@ -45,5 +45,6 @@ dependencies: - sparse - toolz - typing_extensions - - xarray-datatree - zarr + - pip: + - git+https://github.com/xarray-contrib/datatree From ae07dfd69caa5cd712a68aa43a8b18d5105f5c80 Mon Sep 17 00:00:00 2001 From: Tom Nicholas Date: Wed, 1 Feb 2023 11:12:31 -0500 Subject: [PATCH 17/20] Update xarray/__init__.py Co-authored-by: Justus Magin --- xarray/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index 776065fe76c..206f36bf16a 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -55,7 +55,7 @@ try: from datatree import DataTree # noqa except ImportError: - ... + pass # A hardcoded __all__ variable is necessary to appease From 6343104f2c0b5d3da33eda0ef5681babcec787ac Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 1 Feb 2023 11:13:53 -0500 Subject: [PATCH 18/20] also import accessor and open_datatree in top-level init --- xarray/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/__init__.py b/xarray/__init__.py index 206f36bf16a..9585172579c 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -53,7 +53,7 @@ __version__ = "999" try: - from datatree import DataTree # noqa + from datatree import DataTree, register_datatree_accessor, open_datatree # noqa except ImportError: pass From 395a3ae69ee7220d3107db7ea247ba3a0d5c5021 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 1 Feb 2023 11:18:05 -0500 Subject: [PATCH 19/20] importorskip whole test file --- xarray/tests/test_datatree.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index 66d2ac3420d..982a6b2f7be 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -1,19 +1,18 @@ +import pytest + import xarray.testing as xrt -from xarray import Dataset -from xarray.tests import requires_datatree +from xarray import Dataset, DataTree + +pytest.importorskip("datatree") -@requires_datatree def test_import_datatree(): """Just test importing datatree package from xarray-contrib repo""" - from xarray import DataTree DataTree() -@requires_datatree def test_to_datatree(): - from xarray import DataTree ds = Dataset({"a": ("x", [1, 2, 3])}) dt = ds.to_datatree(node_name="group1") From 7cf1d5532cbad1aaf9841cbe959e764ad9661835 Mon Sep 17 00:00:00 2001 From: Thomas Nicholas Date: Wed, 1 Feb 2023 11:27:37 -0500 Subject: [PATCH 20/20] correct package name in wheels --- ci/install-upstream-wheels.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/install-upstream-wheels.sh b/ci/install-upstream-wheels.sh index 65ba2878ae4..074ebf611ca 100755 --- a/ci/install-upstream-wheels.sh +++ b/ci/install-upstream-wheels.sh @@ -20,7 +20,7 @@ conda uninstall -y --force \ bottleneck \ sparse \ flox \ - datatree \ + xarray-datatree \ h5netcdf \ xarray # to limit the runtime of Upstream CI