From e1a36ec056d2d240b5284e63f92396b5b2121c86 Mon Sep 17 00:00:00 2001 From: anjali Date: Thu, 22 Oct 2026 10:55:22 +0530 Subject: [PATCH 1/5] Escalate .apply deprecation to FutureWarning (GH11721) Dataset.apply, GroupBy.apply and Resample.apply have emitted a PendingDeprecationWarning, change that to FutureWarning instead. Add tests to check this warning for GroupBy.apply and Resample.apply. --- doc/whats-new.rst | 7 +++++++ xarray/core/dataset.py | 4 ++-- xarray/core/groupby.py | 8 ++++---- xarray/core/resample.py | 8 ++++---- xarray/tests/test_dataset.py | 4 ++-- xarray/tests/test_groupby.py | 25 +++++++++++++++++++++++++ 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 3abeff78a77..a321e680ce1 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -143,6 +143,13 @@ Deprecations :py:attr:`DataTree.lineage` warns once instead of twice (:issue:`11721`, :pull:`11724`). By `Daisy DAI `_. +- :py:meth:`Dataset.apply`, + :py:meth:`core.groupby.DataArrayGroupBy.apply`, + :py:meth:`core.groupby.DatasetGroupBy.apply`, + :py:meth:`core.resample.DataArrayResample.apply` and + :py:meth:`core.resample.DatasetResample.apply` now emit a ``FutureWarning`` + instead of ``PendingDeprecationWarning``. Use ``.map`` instead (:issue:`11721`). + By `Anjali Kashide `_. Bug Fixes diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index e93a2f48a31..2b867be3f83 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -7145,8 +7145,8 @@ def apply( Dataset.map """ warnings.warn( - "Dataset.apply may be deprecated in the future. Using Dataset.map is encouraged", - PendingDeprecationWarning, + "Dataset.apply is deprecated, use Dataset.map instead.", + FutureWarning, stacklevel=2, ) return self.map(func, keep_attrs, args, **kwargs) diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 3ee4430a28b..2a240d97648 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -1739,8 +1739,8 @@ def apply(self, func, shortcut=False, args=(), **kwargs): DataArrayGroupBy.map """ warnings.warn( - "GroupBy.apply may be deprecated in the future. Using GroupBy.map is encouraged", - PendingDeprecationWarning, + "GroupBy.apply is deprecated, use GroupBy.map instead.", + FutureWarning, stacklevel=2, ) return self.map(func, shortcut=shortcut, args=args, **kwargs) @@ -1919,8 +1919,8 @@ def apply(self, func, args=(), shortcut=None, **kwargs): DatasetGroupBy.map """ warnings.warn( - "GroupBy.apply may be deprecated in the future. Using GroupBy.map is encouraged", - PendingDeprecationWarning, + "GroupBy.apply is deprecated, use GroupBy.map instead.", + FutureWarning, stacklevel=2, ) return self.map(func, shortcut=shortcut, args=args, **kwargs) diff --git a/xarray/core/resample.py b/xarray/core/resample.py index 61b783368cc..0852918910a 100644 --- a/xarray/core/resample.py +++ b/xarray/core/resample.py @@ -383,8 +383,8 @@ def apply(self, func, args=(), shortcut=None, **kwargs): DataArrayResample.map """ warnings.warn( - "Resample.apply may be deprecated in the future. Using Resample.map is encouraged", - PendingDeprecationWarning, + "Resample.apply is deprecated, use Resample.map instead.", + FutureWarning, stacklevel=2, ) return self.map(func=func, shortcut=shortcut, args=args, **kwargs) @@ -470,8 +470,8 @@ def apply(self, func, args=(), shortcut=None, **kwargs): DataSetResample.map """ warnings.warn( - "Resample.apply may be deprecated in the future. Using Resample.map is encouraged", - PendingDeprecationWarning, + "Resample.apply is deprecated, use Resample.map instead.", + FutureWarning, stacklevel=2, ) return self.map(func=func, shortcut=shortcut, args=args, **kwargs) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index a0887c5b9cb..127f4e61c5b 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -6844,11 +6844,11 @@ def modify_attr(da): result = ds.map(modify_attr, keep_attrs=False) assert result["test"].attrs == {"original": "modified", "extra": "added"} - def test_apply_pending_deprecated_map(self) -> None: + def test_apply_deprecated_map(self) -> None: data = create_test_data() data.attrs["foo"] = "bar" - with pytest.warns(PendingDeprecationWarning): + with pytest.warns(FutureWarning, match=r"Dataset\.apply is deprecated"): # data.apply keeps all attrs by default assert_identical(data.apply(np.mean), data.mean()) diff --git a/xarray/tests/test_groupby.py b/xarray/tests/test_groupby.py index 25c5c4ba4f3..eb9c3408d79 100644 --- a/xarray/tests/test_groupby.py +++ b/xarray/tests/test_groupby.py @@ -274,6 +274,31 @@ def func(arg1, arg2, arg3=0): assert_identical(expected, actual) +@pytest.mark.parametrize("use_da", [True, False]) +def test_groupby_apply_deprecated(use_da: bool) -> None: + obj = xr.DataArray([1.0, 2.0, 3.0, 4.0], [("x", [1, 1, 2, 2])]) + if not use_da: + obj = obj.to_dataset(name="foo") + + expected = obj.groupby("x").map(lambda g: g - g.mean()) + with pytest.warns(FutureWarning, match=r"GroupBy\.apply is deprecated"): + actual = obj.groupby("x").apply(lambda g: g - g.mean()) + assert_identical(expected, actual) + + +@pytest.mark.parametrize("use_da", [True, False]) +def test_resample_apply_deprecated(use_da: bool) -> None: + times = pd.date_range("2000-01-01", freq="6h", periods=8) + obj = xr.DataArray(np.arange(8.0), [("time", times)]) + if not use_da: + obj = obj.to_dataset(name="foo") + + expected = obj.resample(time="1D").map(lambda g: g.mean("time")) + with pytest.warns(FutureWarning, match=r"Resample\.apply is deprecated"): + actual = obj.resample(time="1D").apply(lambda g: g.mean("time")) + assert_identical(expected, actual) + + def test_da_groupby_empty() -> None: empty_array = xr.DataArray([], dims="dim") From a355ec79e7e8f40d0ed18f0187d45ba6890534ff Mon Sep 17 00:00:00 2001 From: anjali Date: Thu, 22 Oct 2026 11:38:15 +0530 Subject: [PATCH 2/5] Add PR number to whats-new --- doc/whats-new.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index a321e680ce1..895dd47fbad 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -148,7 +148,8 @@ Deprecations :py:meth:`core.groupby.DatasetGroupBy.apply`, :py:meth:`core.resample.DataArrayResample.apply` and :py:meth:`core.resample.DatasetResample.apply` now emit a ``FutureWarning`` - instead of ``PendingDeprecationWarning``. Use ``.map`` instead (:issue:`11721`). + instead of ``PendingDeprecationWarning``. Use ``.map`` instead (:issue:`11721`, + :pull:`11784`). By `Anjali Kashide `_. From 1135761e36537eae6f96d807a9993be85a521337 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 06:11:59 +0000 Subject: [PATCH 3/5] style: pre-commit fixes --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 895dd47fbad..924dbb77ee9 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -148,7 +148,7 @@ Deprecations :py:meth:`core.groupby.DatasetGroupBy.apply`, :py:meth:`core.resample.DataArrayResample.apply` and :py:meth:`core.resample.DatasetResample.apply` now emit a ``FutureWarning`` - instead of ``PendingDeprecationWarning``. Use ``.map`` instead (:issue:`11721`, + instead of ``PendingDeprecationWarning``. Use ``.map`` instead (:issue:`11721`, :pull:`11784`). By `Anjali Kashide `_. From 746a8dbbf06a4b5eda66bdf2d7ba1f56df44af64 Mon Sep 17 00:00:00 2001 From: anjali Date: Thu, 22 Oct 2026 11:46:56 +0530 Subject: [PATCH 4/5] Fix mypy errors in apply deprecation tests --- xarray/tests/test_groupby.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_groupby.py b/xarray/tests/test_groupby.py index eb9c3408d79..8e50f8d08a1 100644 --- a/xarray/tests/test_groupby.py +++ b/xarray/tests/test_groupby.py @@ -276,7 +276,9 @@ def func(arg1, arg2, arg3=0): @pytest.mark.parametrize("use_da", [True, False]) def test_groupby_apply_deprecated(use_da: bool) -> None: - obj = xr.DataArray([1.0, 2.0, 3.0, 4.0], [("x", [1, 1, 2, 2])]) + obj: xr.DataArray | xr.Dataset = xr.DataArray( + [1.0, 2.0, 3.0, 4.0], [("x", [1, 1, 2, 2])] + ) if not use_da: obj = obj.to_dataset(name="foo") @@ -289,7 +291,7 @@ def test_groupby_apply_deprecated(use_da: bool) -> None: @pytest.mark.parametrize("use_da", [True, False]) def test_resample_apply_deprecated(use_da: bool) -> None: times = pd.date_range("2000-01-01", freq="6h", periods=8) - obj = xr.DataArray(np.arange(8.0), [("time", times)]) + obj: xr.DataArray | xr.Dataset = xr.DataArray(np.arange(8.0), [("time", times)]) if not use_da: obj = obj.to_dataset(name="foo") From 32d64760676d2e0513f6a0b196f4ef4a56b5f5c4 Mon Sep 17 00:00:00 2001 From: anjali Date: Thu, 22 Oct 2026 18:17:43 +0530 Subject: [PATCH 5/5] Use emit_user_level_warning inplace of warnings.warn --- xarray/core/dataset.py | 3 +-- xarray/core/groupby.py | 6 ++---- xarray/core/resample.py | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 2e11ddbd8e8..122211745b0 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -7155,10 +7155,9 @@ def apply( -------- Dataset.map """ - warnings.warn( + emit_user_level_warning( "Dataset.apply is deprecated, use Dataset.map instead.", FutureWarning, - stacklevel=2, ) return self.map(func, keep_attrs, args, **kwargs) diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 2a240d97648..d5078e1beb0 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -1738,10 +1738,9 @@ def apply(self, func, shortcut=False, args=(), **kwargs): -------- DataArrayGroupBy.map """ - warnings.warn( + emit_user_level_warning( "GroupBy.apply is deprecated, use GroupBy.map instead.", FutureWarning, - stacklevel=2, ) return self.map(func, shortcut=shortcut, args=args, **kwargs) @@ -1918,10 +1917,9 @@ def apply(self, func, args=(), shortcut=None, **kwargs): -------- DatasetGroupBy.map """ - warnings.warn( + emit_user_level_warning( "GroupBy.apply is deprecated, use GroupBy.map instead.", FutureWarning, - stacklevel=2, ) return self.map(func, shortcut=shortcut, args=args, **kwargs) diff --git a/xarray/core/resample.py b/xarray/core/resample.py index 0852918910a..49b4ef2d247 100644 --- a/xarray/core/resample.py +++ b/xarray/core/resample.py @@ -1,6 +1,5 @@ from __future__ import annotations -import warnings from collections.abc import Callable, Hashable, Iterable, Sequence from typing import TYPE_CHECKING, Any, Literal, override @@ -10,6 +9,7 @@ ) from xarray.core.groupby import DataArrayGroupByBase, DatasetGroupByBase, GroupBy from xarray.core.types import Dims, InterpOptions, T_Xarray +from xarray.core.utils import emit_user_level_warning if TYPE_CHECKING: from xarray.core.dataarray import DataArray @@ -382,10 +382,9 @@ def apply(self, func, args=(), shortcut=None, **kwargs): -------- DataArrayResample.map """ - warnings.warn( + emit_user_level_warning( "Resample.apply is deprecated, use Resample.map instead.", FutureWarning, - stacklevel=2, ) return self.map(func=func, shortcut=shortcut, args=args, **kwargs) @@ -469,10 +468,9 @@ def apply(self, func, args=(), shortcut=None, **kwargs): -------- DataSetResample.map """ - warnings.warn( + emit_user_level_warning( "Resample.apply is deprecated, use Resample.map instead.", FutureWarning, - stacklevel=2, ) return self.map(func=func, shortcut=shortcut, args=args, **kwargs)