diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 7ce60dc6e81..dbd3ebbfe7e 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -24,10 +24,13 @@ This release increases the minimum required Python version from 3.5.0 to 3.5.3 Breaking changes ~~~~~~~~~~~~~~~~ - The ``isel_points`` and ``sel_points`` methods are removed, having been deprecated +- The ``isel_points`` and ``sel_points`` methods are removed, having been deprecated since v0.10.0. These are redundant with the ``isel`` / ``sel`` methods. See :ref:`vectorized_indexing` for the details By `Maximilian Roos `_ +- The ``inplace`` kwarg for public methods now raises an error, having been deprecated + since v0.11.0. + By `Maximilian Roos `_ New functions/methods ~~~~~~~~~~~~~~~~~~~~~ diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 4bd80553588..e3e543b6621 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -700,30 +700,17 @@ def reset_coords( drop : bool, optional If True, remove coordinates instead of converting them into variables. - inplace : bool, optional - If True, modify this object in place. Otherwise, create a new - object. Returns ------- - Dataset, or DataArray if ``drop == True``, or None if - ``inplace == True`` + Dataset, or DataArray if ``drop == True`` """ - inplace = _check_inplace(inplace) - if inplace and not drop: - raise ValueError( - "cannot reset coordinates in-place on a " - "DataArray without ``drop == True``" - ) + _check_inplace(inplace) if names is None: names = set(self.coords) - set(self.dims) dataset = self.coords.to_dataset().reset_coords(names, drop) if drop: - if inplace: - self._coords = dataset._variables - return None - else: - return self._replace(coords=dataset._variables) + return self._replace(coords=dataset._variables) else: if self.name is None: raise ValueError( @@ -1485,9 +1472,6 @@ def set_index( append : bool, optional If True, append the supplied index(es) to the existing index(es). Otherwise replace the existing index(es) (default). - inplace : bool, optional - If True, set new index(es) in-place. Otherwise, return a new - DataArray object. **indexes_kwargs: optional The keyword arguments form of ``indexes``. One of indexes or indexes_kwargs must be provided. @@ -1496,7 +1480,6 @@ def set_index( ------- obj : DataArray Another DataArray, with this data but replaced coordinates. - Return None if inplace=True. Example ------- @@ -1526,14 +1509,10 @@ def set_index( -------- DataArray.reset_index """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) indexes = either_dict_or_kwargs(indexes, indexes_kwargs, "set_index") coords, _ = merge_indexes(indexes, self._coords, set(), append=append) - if inplace: - self._coords = coords - return None - else: - return self._replace(coords=coords) + return self._replace(coords=coords) def reset_index( self, @@ -1551,36 +1530,29 @@ def reset_index( drop : bool, optional If True, remove the specified indexes and/or multi-index levels instead of extracting them as new coordinates (default: False). - inplace : bool, optional - If True, modify the dataarray in-place. Otherwise, return a new - DataArray object. Returns ------- obj : DataArray Another dataarray, with this dataarray's data but replaced - coordinates. If ``inplace == True``, return None. + coordinates. See Also -------- DataArray.set_index """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) coords, _ = split_indexes( dims_or_levels, self._coords, set(), self._level_coords, drop=drop ) - if inplace: - self._coords = coords - return None - else: - return self._replace(coords=coords) + return self._replace(coords=coords) def reorder_levels( self, dim_order: Mapping[Hashable, Sequence[int]] = None, inplace: bool = None, **dim_order_kwargs: Sequence[int] - ) -> Optional["DataArray"]: + ) -> "DataArray": """Rearrange index levels using input order. Parameters @@ -1589,9 +1561,6 @@ def reorder_levels( Mapping from names matching dimensions and values given by lists representing new level orders. Every given dimension must have a multi-index. - inplace : bool, optional - If True, modify the dataarray in-place. Otherwise, return a new - DataArray object. **dim_order_kwargs: optional The keyword arguments form of ``dim_order``. One of dim_order or dim_order_kwargs must be provided. @@ -1600,9 +1569,9 @@ def reorder_levels( ------- obj : DataArray Another dataarray, with this dataarray's data but replaced - coordinates. If ``inplace == True``, return None. + coordinates. """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) dim_order = either_dict_or_kwargs(dim_order, dim_order_kwargs, "reorder_levels") replace_coords = {} for dim, order in dim_order.items(): @@ -1613,11 +1582,7 @@ def reorder_levels( replace_coords[dim] = IndexVariable(coord.dims, index.reorder_levels(order)) coords = self._coords.copy() coords.update(replace_coords) - if inplace: - self._coords = coords - return None - else: - return self._replace(coords=coords) + return self._replace(coords=coords) def stack( self, diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 4cb5d1454ce..e62b6612ae6 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -1354,9 +1354,6 @@ def set_coords( ---------- names : hashable or iterable of hashables Name(s) of variables in this dataset to convert into coordinates. - inplace : bool, optional - If True, modify this dataset inplace. Otherwise, create a new - object. Returns ------- @@ -1370,13 +1367,13 @@ def set_coords( # DataFrame.set_index? # nb. check in self._variables, not self.data_vars to insure that the # operation is idempotent - inplace = _check_inplace(inplace) + _check_inplace(inplace) if isinstance(names, str) or not isinstance(names, Iterable): names = [names] else: names = list(names) self._assert_all_in_dataset(names) - obj = self if inplace else self.copy() + obj = self.copy() obj._coord_names.update(names) return obj @@ -1396,15 +1393,12 @@ def reset_coords( drop : bool, optional If True, remove coordinates instead of converting them into variables. - inplace : bool, optional - If True, modify this dataset inplace. Otherwise, create a new - object. Returns ------- Dataset """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) if names is None: names = self._coord_names - set(self.dims) else: @@ -1418,7 +1412,7 @@ def reset_coords( raise ValueError( "cannot remove index coordinates with reset_coords: %s" % bad_coords ) - obj = self if inplace else self.copy() + obj = self.copy() obj._coord_names.difference_update(names) if drop: for name in names: @@ -2397,9 +2391,6 @@ def rename( name_dict : dict-like, optional Dictionary whose keys are current variable or dimension names and whose values are the desired names. - inplace : bool, optional - If True, rename variables and dimensions in-place. Otherwise, - return a new dataset object. **names, optional Keyword form of ``name_dict``. One of name_dict or names must be provided. @@ -2416,7 +2407,7 @@ def rename( Dataset.rename_dims DataArray.rename """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) name_dict = either_dict_or_kwargs(name_dict, names, "rename") for k in name_dict.keys(): if k not in self and k not in self.dims: @@ -2428,9 +2419,7 @@ def rename( variables, coord_names, dims, indexes = self._rename_all( name_dict=name_dict, dims_dict=name_dict ) - return self._replace( - variables, coord_names, dims=dims, indexes=indexes, inplace=inplace - ) + return self._replace(variables, coord_names, dims=dims, indexes=indexes) def rename_dims( self, dims_dict: Mapping[Hashable, Hashable] = None, **dims: Hashable @@ -2520,9 +2509,6 @@ def swap_dims( Dictionary whose keys are current dimension names and whose values are new names. Each value must already be a variable in the dataset. - inplace : bool, optional - If True, swap dimensions in-place. Otherwise, return a new dataset - object. Returns ------- @@ -2537,7 +2523,7 @@ def swap_dims( """ # TODO: deprecate this method in favor of a (less confusing) # rename_dims() method that only renames dimensions. - inplace = _check_inplace(inplace) + _check_inplace(inplace) for k, v in dims_dict.items(): if k not in self.dims: raise ValueError( @@ -2570,9 +2556,7 @@ def swap_dims( var.dims = dims variables[k] = var - return self._replace_with_new_dims( - variables, coord_names, indexes=indexes, inplace=inplace - ) + return self._replace_with_new_dims(variables, coord_names, indexes=indexes) def expand_dims( self, @@ -2746,9 +2730,6 @@ def set_index( append : bool, optional If True, append the supplied index(es) to the existing index(es). Otherwise replace the existing index(es) (default). - inplace : bool, optional - If True, set new index(es) in-place. Otherwise, return a new - Dataset object. **indexes_kwargs: optional The keyword arguments form of ``indexes``. One of indexes or indexes_kwargs must be provided. @@ -2790,14 +2771,12 @@ def set_index( Dataset.reset_index Dataset.swap_dims """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) indexes = either_dict_or_kwargs(indexes, indexes_kwargs, "set_index") variables, coord_names = merge_indexes( indexes, self._variables, self._coord_names, append=append ) - return self._replace_vars_and_dims( - variables, coord_names=coord_names, inplace=inplace - ) + return self._replace_vars_and_dims(variables, coord_names=coord_names) def reset_index( self, @@ -2815,9 +2794,6 @@ def reset_index( drop : bool, optional If True, remove the specified indexes and/or multi-index levels instead of extracting them as new coordinates (default: False). - inplace : bool, optional - If True, modify the dataset in-place. Otherwise, return a new - Dataset object. Returns ------- @@ -2828,7 +2804,7 @@ def reset_index( -------- Dataset.set_index """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) variables, coord_names = split_indexes( dims_or_levels, self._variables, @@ -2836,9 +2812,7 @@ def reset_index( cast(Mapping[Hashable, Hashable], self._level_coords), drop=drop, ) - return self._replace_vars_and_dims( - variables, coord_names=coord_names, inplace=inplace - ) + return self._replace_vars_and_dims(variables, coord_names=coord_names) def reorder_levels( self, @@ -2854,9 +2828,6 @@ def reorder_levels( Mapping from names matching dimensions and values given by lists representing new level orders. Every given dimension must have a multi-index. - inplace : bool, optional - If True, modify the dataset in-place. Otherwise, return a new - DataArray object. **dim_order_kwargs: optional The keyword arguments form of ``dim_order``. One of dim_order or dim_order_kwargs must be provided. @@ -2867,7 +2838,7 @@ def reorder_levels( Another dataset, with this dataset's data but replaced coordinates. """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) dim_order = either_dict_or_kwargs(dim_order, dim_order_kwargs, "reorder_levels") variables = self._variables.copy() indexes = OrderedDict(self.indexes) @@ -2880,7 +2851,7 @@ def reorder_levels( variables[dim] = IndexVariable(coord.dims, new_index) indexes[dim] = new_index - return self._replace(variables, indexes=indexes, inplace=inplace) + return self._replace(variables, indexes=indexes) def _stack_once(self, dims, new_dim): variables = OrderedDict() @@ -3176,9 +3147,6 @@ def update(self, other: "DatasetLike", inplace: bool = None) -> "Dataset": - mapping {var name: (dimension name, array-like)} - mapping {var name: (tuple of dimension names, array-like)} - inplace : bool, optional - If True, merge the other dataset into this dataset in-place. - Otherwise, return a new dataset object. Returns ------- @@ -3191,12 +3159,10 @@ def update(self, other: "DatasetLike", inplace: bool = None) -> "Dataset": If any dimensions would have inconsistent sizes in the updated dataset. """ - inplace = _check_inplace(inplace, default=True) + _check_inplace(inplace) variables, coord_names, dims = dataset_update_method(self, other) - return self._replace_vars_and_dims( - variables, coord_names, dims, inplace=inplace - ) + return self._replace_vars_and_dims(variables, coord_names, dims, inplace=True) def merge( self, @@ -3218,9 +3184,6 @@ def merge( ---------- other : Dataset or castable to Dataset Dataset or variables to merge with this dataset. - inplace : bool, optional - If True, merge the other dataset into this dataset in-place. - Otherwise, return a new dataset object. overwrite_vars : Hashable or iterable of Hashable, optional If provided, update variables of these name(s) without checking for conflicts in this dataset. @@ -3257,7 +3220,7 @@ def merge( MergeError If any variables conflict (see ``compat``). """ - inplace = _check_inplace(inplace) + _check_inplace(inplace) variables, coord_names, dims = dataset_merge_method( self, other, @@ -3267,9 +3230,7 @@ def merge( fill_value=fill_value, ) - return self._replace_vars_and_dims( - variables, coord_names, dims, inplace=inplace - ) + return self._replace_vars_and_dims(variables, coord_names, dims) def _assert_all_in_dataset( self, names: Iterable[Hashable], virtual_okay: bool = False diff --git a/xarray/core/utils.py b/xarray/core/utils.py index bf8c9a264e3..a8bb5532f1f 100644 --- a/xarray/core/utils.py +++ b/xarray/core/utils.py @@ -36,19 +36,13 @@ T = TypeVar("T") -def _check_inplace(inplace: Optional[bool], default: bool = False) -> bool: - if inplace is None: - inplace = default - else: - warnings.warn( - "The inplace argument has been deprecated and will be " - "removed in a future version of xarray.", - FutureWarning, - stacklevel=3, +def _check_inplace(inplace: Optional[bool]) -> None: + if inplace is not None: + raise TypeError( + "The `inplace` argument has been removed from xarray. " + "You can achieve an identical effect with python's standard assignment." ) - return inplace - def alias_message(old_name: str, new_name: str) -> str: return "%s has been deprecated. Use %s instead." % (old_name, new_name) diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index 6a68fb73837..798ef66c82e 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -1291,9 +1291,8 @@ def test_reset_coords(self): ) assert_identical(actual, expected) - with pytest.warns(FutureWarning, match="The inplace argument"): - with raises_regex(ValueError, "cannot reset coord"): - data = data.reset_coords(inplace=True) + with pytest.raises(TypeError): + data = data.reset_coords(inplace=True) with raises_regex(ValueError, "cannot be found"): data.reset_coords("foo", drop=True) with raises_regex(ValueError, "cannot be found"): @@ -1702,10 +1701,9 @@ def test_reorder_levels(self): obj = self.mda.reorder_levels(x=["level_2", "level_1"]) assert_identical(obj, expected) - with pytest.warns(FutureWarning, match="The inplace argument"): + with pytest.raises(TypeError): array = self.mda.copy() array.reorder_levels(x=["level_2", "level_1"], inplace=True) - assert_identical(array, expected) array = DataArray([1, 2], dims="x") with pytest.raises(KeyError): diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index 82ae65d955f..a5d9a65d020 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -2325,18 +2325,11 @@ def test_rename_same_name(self): renamed = data.rename(newnames) assert_identical(renamed, data) - @pytest.mark.filterwarnings("ignore:The inplace argument") def test_rename_inplace(self): times = pd.date_range("2000-01-01", periods=3) data = Dataset({"z": ("x", [2, 3, 4]), "t": ("t", times)}) - copied = data.copy() - renamed = data.rename({"x": "y"}) - data.rename({"x": "y"}, inplace=True) - assert_identical(data, renamed) - assert not data.equals(copied) - assert data.dims == {"y": 3, "t": 3} - # check virtual variables - assert_array_equal(data["t.dayofyear"], [1, 2, 3]) + with pytest.raises(TypeError): + data.rename({"x": "y"}, inplace=True) def test_rename_dims(self): original = Dataset({"x": ("x", [0, 1, 2]), "y": ("x", [10, 11, 12]), "z": 42}) @@ -2599,7 +2592,7 @@ def test_set_index(self): obj = ds.set_index(x=mindex.names) assert_identical(obj, expected) - with pytest.warns(FutureWarning, match="The inplace argument"): + with pytest.raises(TypeError): ds.set_index(x=mindex.names, inplace=True) assert_identical(ds, expected) @@ -2624,9 +2617,8 @@ def test_reset_index(self): obj = ds.reset_index("x") assert_identical(obj, expected) - with pytest.warns(FutureWarning, match="The inplace argument"): + with pytest.raises(TypeError): ds.reset_index("x", inplace=True) - assert_identical(ds, expected) def test_reorder_levels(self): ds = create_test_multiindex() @@ -2637,9 +2629,8 @@ def test_reorder_levels(self): reindexed = ds.reorder_levels(x=["level_2", "level_1"]) assert_identical(reindexed, expected) - with pytest.warns(FutureWarning, match="The inplace argument"): + with pytest.raises(TypeError): ds.reorder_levels(x=["level_2", "level_1"], inplace=True) - assert_identical(ds, expected) ds = Dataset({}, coords={"x": [1, 2]}) with raises_regex(ValueError, "has no MultiIndex"): @@ -2779,11 +2770,8 @@ def test_update(self): assert actual_result is actual assert_identical(expected, actual) - with pytest.warns(FutureWarning, match="The inplace argument"): + with pytest.raises(TypeError): actual = data.update(data, inplace=False) - expected = data - assert actual is not expected - assert_identical(expected, actual) other = Dataset(attrs={"new": "attr"}) actual = data.copy()