diff --git a/doc/api.rst b/doc/api.rst index be64e3eac3a..91d64c5de61 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -1644,10 +1644,10 @@ Exceptions .. autosummary:: :toctree: generated/ - AlignmentError - CoordinateValidationError - MergeError - SerializationWarning + errors.AlignmentError + errors.CoordinateValidationError + errors.MergeError + errors.SerializationWarning DataTree -------- @@ -1657,9 +1657,9 @@ Exceptions raised when manipulating trees. .. autosummary:: :toctree: generated/ - TreeIsomorphismError - InvalidTreeError - NotFoundInTreeError + errors.TreeIsomorphismError + errors.InvalidTreeError + errors.NotFoundInTreeError Advanced API ============ diff --git a/doc/user-guide/combining.rst b/doc/user-guide/combining.rst index 53d5fc17cbd..a9dc499c811 100644 --- a/doc/user-guide/combining.rst +++ b/doc/user-guide/combining.rst @@ -99,7 +99,7 @@ coordinates: other = xr.Dataset({"bar": ("x", [1, 2, 3, 4]), "x": list("abcd")}) xr.merge([ds, other]) -This ensures that ``merge`` is non-destructive. ``xarray.MergeError`` is raised +This ensures that ``merge`` is non-destructive. ``xarray.errors.MergeError`` is raised if you attempt to merge two variables with the same name but different values: .. ipython:: diff --git a/doc/user-guide/data-structures.rst b/doc/user-guide/data-structures.rst index 5ce60e5c405..618d72fda85 100644 --- a/doc/user-guide/data-structures.rst +++ b/doc/user-guide/data-structures.rst @@ -610,7 +610,7 @@ We have created a tree with three nodes in it: Consistency checks are enforced. For instance, if we try to create a cycle, where the root node is also a child of a descendant, the constructor will raise -an (:py:class:`~xarray.InvalidTreeError`): +an (:py:class:`~xarray.errors.InvalidTreeError`): .. ipython:: python :okexcept: diff --git a/doc/user-guide/hierarchical-data.rst b/doc/user-guide/hierarchical-data.rst index 5f3a341323f..0291a7671fe 100644 --- a/doc/user-guide/hierarchical-data.rst +++ b/doc/user-guide/hierarchical-data.rst @@ -143,7 +143,7 @@ We can add Herbert to the family tree without displacing Homer by :py:meth:`~xar Certain manipulations of our tree are forbidden, if they would create an inconsistent result. In episode 51 of the show Futurama, Philip J. Fry travels back in time and accidentally becomes his own Grandfather. -If we try similar time-travelling hijinks with Homer, we get a :py:class:`~xarray.InvalidTreeError` raised: +If we try similar time-travelling hijinks with Homer, we get a :py:class:`~xarray.errors.InvalidTreeError` raised: .. ipython:: python :okexcept: @@ -621,7 +621,7 @@ each tree needs to have the same structure. Specifically two trees can only be c or "isomorphic", if the full paths to all of their descendent nodes are the same. Applying :py:func:`~xarray.group_subtrees` to trees with different structures -raises :py:class:`~xarray.TreeIsomorphismError`: +raises :py:class:`~xarray.errors.TreeIsomorphismError`: .. ipython:: python :okexcept: diff --git a/xarray/__init__.py b/xarray/__init__.py index d1001b4470a..4fe9fb38d5c 100644 --- a/xarray/__init__.py +++ b/xarray/__init__.py @@ -1,6 +1,6 @@ from importlib.metadata import version as _version -from xarray import coders, groupers, testing, tutorial, ufuncs +from xarray import coders, errors, groupers, testing, tutorial, ufuncs from xarray.backends.api import ( load_dataarray, load_dataset, @@ -26,9 +26,9 @@ polyval, where, ) -from xarray.conventions import SerializationWarning, decode_cf +from xarray.conventions import decode_cf from xarray.core.common import ALL_DIMS, full_like, ones_like, zeros_like -from xarray.core.coordinates import Coordinates, CoordinateValidationError +from xarray.core.coordinates import Coordinates from xarray.core.dataarray import DataArray from xarray.core.dataset import Dataset from xarray.core.datatree import DataTree @@ -42,19 +42,25 @@ from xarray.core.indexing import IndexSelResult from xarray.core.options import get_options, set_options from xarray.core.parallel import map_blocks -from xarray.core.treenode import ( +from xarray.core.treenode import group_subtrees +from xarray.core.variable import IndexVariable, Variable, as_variable + +# import custom error classes in root namespace for backward compatibility +from xarray.errors import ( + AlignmentError, + CoordinateValidationError, InvalidTreeError, + MergeError, NotFoundInTreeError, + SerializationWarning, TreeIsomorphismError, - group_subtrees, ) -from xarray.core.variable import IndexVariable, Variable, as_variable from xarray.namedarray.core import NamedArray -from xarray.structure.alignment import AlignmentError, align, broadcast +from xarray.structure.alignment import align, broadcast from xarray.structure.chunks import unify_chunks from xarray.structure.combine import combine_by_coords, combine_nested from xarray.structure.concat import concat -from xarray.structure.merge import Context, MergeError, merge +from xarray.structure.merge import Context, merge from xarray.util.print_versions import show_versions try: @@ -69,6 +75,7 @@ __all__ = ( # noqa: RUF022 # Sub-packages "coders", + "errors", "groupers", "testing", "tutorial", diff --git a/xarray/backends/common.py b/xarray/backends/common.py index 58a98598a5b..ae2264efcf3 100644 --- a/xarray/backends/common.py +++ b/xarray/backends/common.py @@ -12,7 +12,6 @@ import pandas as pd from xarray.coding import strings, variables -from xarray.coding.variables import SerializationWarning from xarray.conventions import cf_encoder from xarray.core import indexing from xarray.core.datatree import DataTree, Variable @@ -24,6 +23,7 @@ emit_user_level_warning, is_remote_uri, ) +from xarray.errors import SerializationWarning from xarray.namedarray.parallelcompat import get_chunked_array_type from xarray.namedarray.pycompat import is_chunked_array from xarray.namedarray.utils import is_duck_dask_array diff --git a/xarray/coding/common.py b/xarray/coding/common.py index 1b455009668..ffdf8d1c6d3 100644 --- a/xarray/coding/common.py +++ b/xarray/coding/common.py @@ -15,10 +15,6 @@ T_Name = Union[Hashable, None] -class SerializationWarning(RuntimeWarning): - """Warnings about encoding/decoding issues in serialization.""" - - class VariableCoder: """Base class for encoding and decoding transformations on variables. diff --git a/xarray/coding/times.py b/xarray/coding/times.py index fdecfe77ede..566feef60d2 100644 --- a/xarray/coding/times.py +++ b/xarray/coding/times.py @@ -12,7 +12,6 @@ from pandas.errors import OutOfBoundsDatetime, OutOfBoundsTimedelta from xarray.coding.common import ( - SerializationWarning, VariableCoder, lazy_elemwise_func, pop_to, @@ -27,6 +26,7 @@ from xarray.core.formatting import first_n_items, format_timestamp, last_item from xarray.core.utils import attempt_import, emit_user_level_warning from xarray.core.variable import Variable +from xarray.errors import SerializationWarning from xarray.namedarray.parallelcompat import T_ChunkedArray, get_chunked_array_type from xarray.namedarray.pycompat import is_chunked_array, to_numpy from xarray.namedarray.utils import is_duck_dask_array diff --git a/xarray/coding/variables.py b/xarray/coding/variables.py index 1b7bc95e2b4..a798d88b397 100644 --- a/xarray/coding/variables.py +++ b/xarray/coding/variables.py @@ -11,7 +11,6 @@ import pandas as pd from xarray.coding.common import ( - SerializationWarning, VariableCoder, lazy_elemwise_func, pop_to, @@ -22,6 +21,7 @@ from xarray.coding.times import CFDatetimeCoder, CFTimedeltaCoder from xarray.core import dtypes, duck_array_ops, indexing from xarray.core.variable import Variable +from xarray.errors import SerializationWarning if TYPE_CHECKING: T_VarTuple = tuple[tuple[Hashable, ...], Any, dict, dict] diff --git a/xarray/conventions.py b/xarray/conventions.py index 071dab43c28..28ee3d37d17 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -10,7 +10,7 @@ from xarray.coders import CFDatetimeCoder, CFTimedeltaCoder from xarray.coding import strings, variables -from xarray.coding.variables import SerializationWarning, pop_to +from xarray.coding.variables import pop_to from xarray.core import indexing from xarray.core.common import ( _contains_datetime_like_objects, @@ -18,6 +18,7 @@ ) from xarray.core.utils import emit_user_level_warning from xarray.core.variable import IndexVariable, Variable +from xarray.errors import SerializationWarning from xarray.namedarray.utils import is_duck_dask_array CF_RELATED_DATA = ( diff --git a/xarray/core/coordinates.py b/xarray/core/coordinates.py index 13fe0a791bb..03420369841 100644 --- a/xarray/core/coordinates.py +++ b/xarray/core/coordinates.py @@ -29,6 +29,7 @@ emit_user_level_warning, ) from xarray.core.variable import Variable, as_variable, calculate_dimensions +from xarray.errors import CoordinateValidationError from xarray.structure.alignment import Aligner from xarray.structure.merge import merge_coordinates_without_align, merge_coords @@ -1146,10 +1147,6 @@ def create_coords_with_default_indexes( return new_coords -class CoordinateValidationError(ValueError): - """Error class for Xarray coordinate validation failures.""" - - def validate_dataarray_coords( shape: tuple[int, ...], coords: Coordinates | Mapping[Hashable, Variable], diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 5a578128d1a..f095d20cbbf 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -72,6 +72,7 @@ as_compatible_data, as_variable, ) +from xarray.errors import MergeError from xarray.plot.accessor import DataArrayPlotAccessor from xarray.plot.utils import _get_units_from_attrs from xarray.structure import alignment @@ -81,7 +82,7 @@ align, ) from xarray.structure.chunks import unify_chunks -from xarray.structure.merge import PANDAS_TYPES, MergeError +from xarray.structure.merge import PANDAS_TYPES from xarray.util.deprecation_helpers import _deprecate_positional_args, deprecate_dims if TYPE_CHECKING: diff --git a/xarray/core/indexes.py b/xarray/core/indexes.py index 8babb885a5e..1fb589986cd 100644 --- a/xarray/core/indexes.py +++ b/xarray/core/indexes.py @@ -220,8 +220,8 @@ def should_add_coord_to_array( Returning ``False`` will either: - - raise a :py:class:`CoordinateValidationError` when passing the - coordinate directly to a new or an existing DataArray, e.g., via + - raise a :py:class:`~xarray.errors.CoordinateValidationError` when passing + the coordinate directly to a new or an existing DataArray, e.g., via ``DataArray.__init__()`` or ``DataArray.assign_coords()`` - drop the coordinate (and therefore drop the index) when a new diff --git a/xarray/core/treenode.py b/xarray/core/treenode.py index 0d97bd036ab..97e95e13874 100644 --- a/xarray/core/treenode.py +++ b/xarray/core/treenode.py @@ -13,19 +13,12 @@ from xarray.core.types import Self from xarray.core.utils import Frozen, is_dict_like +from xarray.errors import InvalidTreeError, NotFoundInTreeError, TreeIsomorphismError if TYPE_CHECKING: from xarray.core.types import T_DataArray -class InvalidTreeError(Exception): - """Raised when user attempts to create an invalid tree in some way.""" - - -class NotFoundInTreeError(ValueError): - """Raised when operation can't be completed because one node is not part of the expected tree.""" - - class NodePath(PurePosixPath): """Represents a path from one node to another within a tree.""" @@ -799,10 +792,6 @@ def _path_to_ancestor(self, ancestor: NamedNode) -> NodePath: return NodePath(path_upwards) -class TreeIsomorphismError(ValueError): - """Error raised if two tree objects do not share the same node structure.""" - - def group_subtrees( *trees: AnyNamedNode, ) -> Iterator[tuple[str, tuple[AnyNamedNode, ...]]]: diff --git a/xarray/errors.py b/xarray/errors.py new file mode 100644 index 00000000000..56ec4a6c3bb --- /dev/null +++ b/xarray/errors.py @@ -0,0 +1,41 @@ +""" +This module exposes Xarray's custom exceptions & warnings. +""" + + +class AlignmentError(ValueError): + """Error class for alignment failures due to incompatible arguments.""" + + +class CoordinateValidationError(ValueError): + """Error class for Xarray coordinate validation failures.""" + + +class MergeError(ValueError): + """Error class for merge failures due to incompatible arguments.""" + + +class InvalidTreeError(Exception): + """Raised when user attempts to create an invalid tree in some way.""" + + +class NotFoundInTreeError(ValueError): + """Raised when operation can't be completed because one node is not part of the expected tree.""" + + +class TreeIsomorphismError(ValueError): + """Error raised if two tree objects do not share the same node structure.""" + + +class SerializationWarning(RuntimeWarning): + """Warnings about encoding/decoding issues in serialization.""" + + +__all__ = [ + "AlignmentError", + "CoordinateValidationError", + "InvalidTreeError", + "MergeError", + "SerializationWarning", + "TreeIsomorphismError", +] diff --git a/xarray/structure/alignment.py b/xarray/structure/alignment.py index ea90519143c..1e6dbb00859 100644 --- a/xarray/structure/alignment.py +++ b/xarray/structure/alignment.py @@ -22,6 +22,7 @@ from xarray.core.types import T_Alignable from xarray.core.utils import is_dict_like, is_full_slice from xarray.core.variable import Variable, as_compatible_data, calculate_dimensions +from xarray.errors import AlignmentError if TYPE_CHECKING: from xarray.core.dataarray import DataArray @@ -35,10 +36,6 @@ ) -class AlignmentError(ValueError): - """Error class for alignment failures due to incompatible arguments.""" - - def reindex_variables( variables: Mapping[Any, Variable], dim_pos_indexers: Mapping[Any, Any], @@ -837,7 +834,7 @@ def align( >>> a, b = xr.align(x, y, join="exact") Traceback (most recent call last): ... - xarray.structure.alignment.AlignmentError: cannot align objects with join='exact' ... + xarray.errors.AlignmentError: cannot align objects with join='exact' ... >>> a, b = xr.align(x, y, join="override") >>> a diff --git a/xarray/structure/merge.py b/xarray/structure/merge.py index 7d773ce0b4b..c42c970cdc2 100644 --- a/xarray/structure/merge.py +++ b/xarray/structure/merge.py @@ -16,6 +16,7 @@ ) from xarray.core.utils import Frozen, compat_dict_union, dict_equiv, equivalent from xarray.core.variable import Variable, as_variable, calculate_dimensions +from xarray.errors import MergeError from xarray.structure.alignment import deep_align if TYPE_CHECKING: @@ -78,13 +79,6 @@ def broadcast_dimension_size(variables: list[Variable]) -> dict[Hashable, int]: return dims -class MergeError(ValueError): - """Error class for merge failures due to incompatible arguments.""" - - # inherits from ValueError for backward compatibility - # TODO: move this to an xarray.exceptions module? - - def unique_variable( name: Hashable, variables: list[Variable], @@ -942,7 +936,7 @@ def merge( >>> xr.merge([x, y, z], join="exact") Traceback (most recent call last): ... - xarray.structure.alignment.AlignmentError: cannot align objects with join='exact' where ... + xarray.errors.AlignmentError: cannot align objects with join='exact' where ... Raises ------ diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 95c53786f86..c5ff50dff7e 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -52,11 +52,11 @@ from xarray.coders import CFDatetimeCoder, CFTimedeltaCoder from xarray.coding.cftime_offsets import date_range from xarray.coding.strings import check_vlen_dtype, create_vlen_dtype -from xarray.coding.variables import SerializationWarning from xarray.conventions import encode_dataset_coordinates from xarray.core import indexing from xarray.core.options import set_options from xarray.core.utils import module_available +from xarray.errors import SerializationWarning from xarray.namedarray.pycompat import array_type from xarray.tests import ( assert_allclose, @@ -4739,7 +4739,7 @@ def test_open_mfdataset_dataset_combine_attrs( ds.to_netcdf(f) if expect_error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): xr.open_mfdataset( files, combine="nested", diff --git a/xarray/tests/test_coding_times.py b/xarray/tests/test_coding_times.py index e4541bad7e6..1f7b28e82a1 100644 --- a/xarray/tests/test_coding_times.py +++ b/xarray/tests/test_coding_times.py @@ -33,11 +33,11 @@ infer_datetime_units, infer_timedelta_units, ) -from xarray.coding.variables import SerializationWarning from xarray.conventions import _update_bounds_attributes, cf_encoder from xarray.core.common import contains_cftime_datetimes from xarray.core.types import PDDatetimeUnitOptions from xarray.core.utils import is_duck_dask_array +from xarray.errors import SerializationWarning from xarray.testing import assert_equal, assert_identical from xarray.tests import ( _ALL_CALENDARS, diff --git a/xarray/tests/test_combine.py b/xarray/tests/test_combine.py index 80a795c4c52..c003359a3e7 100644 --- a/xarray/tests/test_combine.py +++ b/xarray/tests/test_combine.py @@ -8,13 +8,13 @@ from xarray import ( DataArray, Dataset, - MergeError, combine_by_coords, combine_nested, concat, merge, ) from xarray.core import dtypes +from xarray.errors import MergeError from xarray.structure.combine import ( _check_shape_tile_ids, _combine_all_along_first_dim, diff --git a/xarray/tests/test_computation.py b/xarray/tests/test_computation.py index cb12f3df534..50f5db5f741 100644 --- a/xarray/tests/test_computation.py +++ b/xarray/tests/test_computation.py @@ -787,7 +787,7 @@ def test_keep_attrs_strategies_variable(strategy, attrs, expected, error) -> Non c = xr.Variable("x", [0, 1], attrs=attrs[2]) if error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): apply_ufunc(lambda *args: sum(args), a, b, c, keep_attrs=strategy) else: expected = xr.Variable("x", [0, 3], attrs=expected) @@ -856,7 +856,7 @@ def test_keep_attrs_strategies_dataarray(strategy, attrs, expected, error) -> No c = xr.DataArray(dims="x", data=[0, 1], attrs=attrs[2]) if error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): apply_ufunc(lambda *args: sum(args), a, b, c, keep_attrs=strategy) else: expected = xr.DataArray(dims="x", data=[0, 3], attrs=expected) @@ -947,7 +947,7 @@ def test_keep_attrs_strategies_dataarray_variables( ) if error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): apply_ufunc(lambda *args: sum(args), a, b, c, keep_attrs=strategy) else: dim_attrs, coord_attrs = compute_attrs(expected, {}) @@ -1021,7 +1021,7 @@ def test_keep_attrs_strategies_dataset(strategy, attrs, expected, error) -> None c = xr.Dataset({"a": ("x", [0, 1])}, attrs=attrs[2]) if error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): apply_ufunc(lambda *args: sum(args), a, b, c, keep_attrs=strategy) else: expected = xr.Dataset({"a": ("x", [0, 3])}, attrs=expected) @@ -1109,7 +1109,7 @@ def test_keep_attrs_strategies_dataset_variables( ) if error: - with pytest.raises(xr.MergeError): + with pytest.raises(xr.errors.MergeError): apply_ufunc(lambda *args: sum(args), a, b, c, keep_attrs=strategy) else: data_attrs, dim_attrs, coord_attrs = compute_attrs(expected, {}) diff --git a/xarray/tests/test_concat.py b/xarray/tests/test_concat.py index 49c6490d819..ec00b243185 100644 --- a/xarray/tests/test_concat.py +++ b/xarray/tests/test_concat.py @@ -12,7 +12,7 @@ from xarray.core import dtypes from xarray.core.coordinates import Coordinates from xarray.core.indexes import PandasIndex -from xarray.structure import merge +from xarray.errors import MergeError from xarray.tests import ( ConcatenatableArray, InaccessibleArray, @@ -587,7 +587,7 @@ def test_concat_coords(self): actual = concat(objs, dim="x", coords=coords) assert_identical(expected, actual) for coords in ["minimal", []]: - with pytest.raises(merge.MergeError, match="conflicting values"): + with pytest.raises(MergeError, match="conflicting values"): concat(objs, dim="x", coords=coords) def test_concat_constant_index(self): @@ -599,7 +599,7 @@ def test_concat_constant_index(self): for mode in ["different", "all", ["foo"]]: actual = concat([ds1, ds2], "y", data_vars=mode) assert_identical(expected, actual) - with pytest.raises(merge.MergeError, match="conflicting values"): + with pytest.raises(MergeError, match="conflicting values"): # previously dim="y", and raised error which makes no sense. # "foo" has dimension "y" so minimal should concatenate it? concat([ds1, ds2], "new_dim", data_vars="minimal") diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 961df78154e..d0934f5ec60 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -9,7 +9,6 @@ from xarray import ( Dataset, - SerializationWarning, Variable, coding, conventions, @@ -20,6 +19,7 @@ from xarray.backends.memory import InMemoryDataStore from xarray.coders import CFDatetimeCoder, CFTimedeltaCoder from xarray.conventions import decode_cf +from xarray.errors import SerializationWarning from xarray.testing import assert_identical from xarray.tests import ( assert_array_equal, diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index e7acdcdd4f3..f84a605eac7 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -33,7 +33,7 @@ from xarray.coders import CFDatetimeCoder from xarray.core import dtypes from xarray.core.common import full_like -from xarray.core.coordinates import Coordinates, CoordinateValidationError +from xarray.core.coordinates import Coordinates from xarray.core.indexes import ( Index, PandasIndex, @@ -41,6 +41,7 @@ ) from xarray.core.types import QueryEngineOptions, QueryParserOptions from xarray.core.utils import is_scalar +from xarray.errors import CoordinateValidationError from xarray.testing import _assert_internal_invariants from xarray.tests import ( InaccessibleArray, @@ -2413,9 +2414,13 @@ def test_inplace_math_error(self) -> None: def test_inplace_math_automatic_alignment(self) -> None: a = DataArray(range(5), [("x", range(5))]) b = DataArray(range(1, 6), [("x", range(1, 6))]) - with pytest.raises(xr.MergeError, match="Automatic alignment is not supported"): + with pytest.raises( + xr.errors.MergeError, match="Automatic alignment is not supported" + ): a += b - with pytest.raises(xr.MergeError, match="Automatic alignment is not supported"): + with pytest.raises( + xr.errors.MergeError, match="Automatic alignment is not supported" + ): b += a def test_math_name(self) -> None: diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index ac186a7d351..bdd3cda7538 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -23,11 +23,9 @@ import xarray as xr from xarray import ( - AlignmentError, DataArray, Dataset, IndexVariable, - MergeError, Variable, align, backends, @@ -42,6 +40,7 @@ from xarray.core.indexes import Index, PandasIndex from xarray.core.types import ArrayLike from xarray.core.utils import is_scalar +from xarray.errors import AlignmentError, MergeError from xarray.groupers import TimeResampler from xarray.namedarray.pycompat import array_type, integer_types from xarray.testing import _assert_internal_invariants diff --git a/xarray/tests/test_datatree.py b/xarray/tests/test_datatree.py index 23bc194695c..ca8bcfb497a 100644 --- a/xarray/tests/test_datatree.py +++ b/xarray/tests/test_datatree.py @@ -12,7 +12,7 @@ from xarray import DataArray, Dataset from xarray.core.coordinates import DataTreeCoordinates from xarray.core.datatree import DataTree -from xarray.core.treenode import NotFoundInTreeError +from xarray.errors import NotFoundInTreeError from xarray.testing import assert_equal, assert_identical from xarray.tests import ( assert_array_equal, @@ -2300,7 +2300,7 @@ def test_dont_broadcast_single_node_tree(self) -> None: node = dt["/subnode"] with pytest.raises( - xr.TreeIsomorphismError, + xr.errors.TreeIsomorphismError, match=re.escape(r"children at root node do not match: ['subnode'] vs []"), ): dt * node diff --git a/xarray/tests/test_datatree_mapping.py b/xarray/tests/test_datatree_mapping.py index 277a19887eb..7dd23509457 100644 --- a/xarray/tests/test_datatree_mapping.py +++ b/xarray/tests/test_datatree_mapping.py @@ -5,7 +5,7 @@ import xarray as xr from xarray.core.datatree_mapping import map_over_datasets -from xarray.core.treenode import TreeIsomorphismError +from xarray.errors import TreeIsomorphismError from xarray.testing import assert_equal, assert_identical empty = xr.Dataset() diff --git a/xarray/tests/test_merge.py b/xarray/tests/test_merge.py index 302d26df8f3..7981dc89028 100644 --- a/xarray/tests/test_merge.py +++ b/xarray/tests/test_merge.py @@ -5,8 +5,8 @@ import xarray as xr from xarray.core import dtypes +from xarray.errors import MergeError from xarray.structure import merge -from xarray.structure.merge import MergeError from xarray.testing import assert_equal, assert_identical from xarray.tests.test_dataset import create_test_data diff --git a/xarray/tests/test_treenode.py b/xarray/tests/test_treenode.py index 5f9c586fce2..5db3d00e080 100644 --- a/xarray/tests/test_treenode.py +++ b/xarray/tests/test_treenode.py @@ -5,13 +5,13 @@ import pytest from xarray.core.treenode import ( - InvalidTreeError, NamedNode, NodePath, TreeNode, group_subtrees, zip_subtrees, ) +from xarray.errors import InvalidTreeError class TestFamilyTree: diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py index ede065eac37..36e0fa270b3 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units.py @@ -3960,11 +3960,11 @@ class TestDataset: @pytest.mark.parametrize( "unit,error", ( - pytest.param(1, xr.MergeError, id="no_unit"), + pytest.param(1, xr.errors.MergeError, id="no_unit"), pytest.param( - unit_registry.dimensionless, xr.MergeError, id="dimensionless" + unit_registry.dimensionless, xr.errors.MergeError, id="dimensionless" ), - pytest.param(unit_registry.s, xr.MergeError, id="incompatible_unit"), + pytest.param(unit_registry.s, xr.errors.MergeError, id="incompatible_unit"), pytest.param(unit_registry.mm, None, id="compatible_unit"), pytest.param(unit_registry.m, None, id="same_unit"), ), @@ -5554,12 +5554,12 @@ def test_content_manipulation(self, func, variant, dtype): @pytest.mark.parametrize( "unit,error", ( - pytest.param(1, xr.MergeError, id="no_unit"), + pytest.param(1, xr.errors.MergeError, id="no_unit"), pytest.param( - unit_registry.dimensionless, xr.MergeError, id="dimensionless" + unit_registry.dimensionless, xr.errors.MergeError, id="dimensionless" ), - pytest.param(unit_registry.s, xr.MergeError, id="incompatible_unit"), - pytest.param(unit_registry.cm, xr.MergeError, id="compatible_unit"), + pytest.param(unit_registry.s, xr.errors.MergeError, id="incompatible_unit"), + pytest.param(unit_registry.cm, xr.errors.MergeError, id="compatible_unit"), pytest.param(unit_registry.m, None, id="identical_unit"), ), )