Repository: dask/dask (python)

Issue:
Rename shuffle to shuffle_method in remaining methods
Mostly groupby aggregations and drop_duplicates (maybe unique and nunique)


please grep the code base.



Pull request description:
Rename shuffle to shuffle_method in remaining methods
- [x] Closes #10782
- [x] Tests added / passed
- [x] Passes `pre-commit run --all-files`

---

Is there suppose to be a deprecation period before this renaming? 

Patch:
diff --git a/dask/dataframe/core.py b/dask/dataframe/core.py
index 67e829a52..6f58192a3 100644
--- a/dask/dataframe/core.py
+++ b/dask/dataframe/core.py
@@ -197,9 +197,9 @@ def _concat(args, ignore_index=False):
     )
 
 
-def _determine_split_out_shuffle(shuffle, split_out):
+def _determine_split_out_shuffle(shuffle_method, split_out):
     """Determine the default shuffle behavior based on split_out"""
-    if shuffle is None:
+    if shuffle_method is None:
         if split_out > 1:
             # FIXME: This is using a different default but it is not fully
             # understood why this is a better choice.
@@ -209,9 +209,9 @@ def _determine_split_out_shuffle(shuffle, split_out):
             return config.get("dataframe.shuffle.method", None) or "tasks"
         else:
             return False
-    if shuffle is True:
+    if shuffle_method is True:
         return config.get("dataframe.shuffle.method", None) or "tasks"
-    return shuffle
+    return shuffle_method
 
 
 def finalize(results):
@@ -935,6 +935,7 @@ Dask Name: {name}, {layers}"""
         # Return `split_out` partitions
         return deduplicated.repartition(npartitions=split_out)
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(
         pd.DataFrame,
         inconsistencies="keep=False will raise a ``NotImplementedError``",
@@ -944,7 +945,7 @@ Dask Name: {name}, {layers}"""
         subset=None,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         ignore_index=False,
         **kwargs,
     ):
@@ -964,12 +965,12 @@ Dask Name: {name}, {layers}"""
         # Check if we should use a shuffle-based algorithm,
         # which is typically faster when we are not reducing
         # to a small number of partitions
-        shuffle = _determine_split_out_shuffle(shuffle, split_out)
-        if shuffle:
+        shuffle_method = _determine_split_out_shuffle(shuffle_method, split_out)
+        if shuffle_method:
             return self._drop_duplicates_shuffle(
                 split_out,
                 split_every,
-                shuffle,
+                shuffle_method,
                 ignore_index,
                 **kwargs,
             )
@@ -4883,6 +4884,7 @@ class Index(Series):
             token=self._token_prefix + "memory-usage",
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(
         pd.Index,
         inconsistencies="keep=False will raise a ``NotImplementedError``",
@@ -4891,7 +4893,7 @@ class Index(Series):
         self,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         **kwargs,
     ):
         if not self.known_divisions:
@@ -4899,7 +4901,7 @@ class Index(Series):
             return super().drop_duplicates(
                 split_every=split_every,
                 split_out=split_out,
-                shuffle=shuffle,
+                shuffle_method=shuffle_method,
                 **kwargs,
             )
 
diff --git a/dask/dataframe/groupby.py b/dask/dataframe/groupby.py
index 8acdeb251..456e8cf19 100644
--- a/dask/dataframe/groupby.py
+++ b/dask/dataframe/groupby.py
@@ -48,7 +48,14 @@ from dask.dataframe.utils import (
 )
 from dask.highlevelgraph import HighLevelGraph
 from dask.typing import no_default
-from dask.utils import M, _deprecated, derived_from, funcname, itemgetter
+from dask.utils import (
+    M,
+    _deprecated,
+    _deprecated_kwarg,
+    derived_from,
+    funcname,
+    itemgetter,
+)
 
 if PANDAS_GE_140:
     from pandas.core.apply import reconstruct_func, validate_func_kwargs
@@ -1516,7 +1523,7 @@ class _GroupBy:
         meta=None,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         chunk_kwargs=None,
         aggregate_kwargs=None,
         columns=None,
@@ -1525,7 +1532,7 @@ class _GroupBy:
         Aggregation with a single function/aggfunc rather than a compound spec
         like in GroupBy.aggregate
         """
-        shuffle = _determine_split_out_shuffle(shuffle, split_out)
+        shuffle_method = _determine_split_out_shuffle(shuffle_method, split_out)
 
         if aggfunc is None:
             aggfunc = func
@@ -1548,7 +1555,7 @@ class _GroupBy:
         token = self._token_prefix + token
         levels = _determine_levels(self.by)
 
-        if shuffle:
+        if shuffle_method:
             return _shuffle_aggregate(
                 args,
                 chunk=_apply_chunk,
@@ -1570,7 +1577,7 @@ class _GroupBy:
                 token=token,
                 split_every=split_every,
                 split_out=split_out,
-                shuffle_method=shuffle,
+                shuffle_method=shuffle_method,
                 sort=self.sort,
             )
 
@@ -1807,13 +1814,14 @@ class _GroupBy:
             "cumcount", chunk=M.cumcount, aggregate=_cumcount_aggregate, initial=-1
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     @numeric_only_deprecate_default
     def sum(
         self,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         min_count=None,
         numeric_only=no_default,
     ):
@@ -1823,7 +1831,7 @@ class _GroupBy:
             token="sum",
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
@@ -1832,13 +1840,14 @@ class _GroupBy:
         else:
             return result
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     @numeric_only_deprecate_default
     def prod(
         self,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         min_count=None,
         numeric_only=no_default,
     ):
@@ -1848,7 +1857,7 @@ class _GroupBy:
             token="prod",
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
@@ -1857,39 +1866,54 @@ class _GroupBy:
         else:
             return result
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
-    def min(self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default):
+    def min(
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
+    ):
         numeric_kwargs = get_numeric_only_kwargs(numeric_only)
         return self._single_agg(
             func=M.min,
             token="min",
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
-    def max(self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default):
+    def max(
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
+    ):
         numeric_kwargs = get_numeric_only_kwargs(numeric_only)
         return self._single_agg(
             func=M.max,
             token="max",
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.DataFrame)
     @numeric_only_deprecate_default
     def idxmin(
         self,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         axis=no_default,
         skipna=True,
         numeric_only=no_default,
@@ -1913,18 +1937,19 @@ class _GroupBy:
             aggfunc=M.first,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=chunk_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.DataFrame)
     @numeric_only_deprecate_default
     def idxmax(
         self,
         split_every=None,
         split_out=1,
-        shuffle=None,
+        shuffle_method=None,
         axis=no_default,
         skipna=True,
         numeric_only=no_default,
@@ -1949,51 +1974,64 @@ class _GroupBy:
             aggfunc=M.first,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=chunk_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
-    def count(self, split_every=None, split_out=1, shuffle=None):
+    def count(self, split_every=None, split_out=1, shuffle_method=None):
         return self._single_agg(
             func=M.count,
             token="count",
             aggfunc=M.sum,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     @numeric_only_not_implemented
     def mean(
-        self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
     ):
         # We sometimes emit this warning ourselves. We ignore it here so users only see it once.
         with check_numeric_only_deprecation():
             s = self.sum(
                 split_every=split_every,
                 split_out=split_out,
-                shuffle=shuffle,
+                shuffle_method=shuffle_method,
                 numeric_only=numeric_only,
             )
-        c = self.count(split_every=split_every, split_out=split_out, shuffle=shuffle)
+        c = self.count(
+            split_every=split_every, split_out=split_out, shuffle_method=shuffle_method
+        )
         if is_dataframe_like(s):
             c = c[s.columns]
         return s / c
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     def median(
-        self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
     ):
-        if shuffle is False:
+        if shuffle_method is False:
             raise ValueError(
                 "In order to aggregate with 'median', you must use shuffling-based "
                 "aggregation (e.g., shuffle='tasks')"
             )
 
-        shuffle = shuffle or _determine_split_out_shuffle(True, split_out)
+        shuffle_method = shuffle_method or _determine_split_out_shuffle(True, split_out)
         numeric_only_kwargs = get_numeric_only_kwargs(numeric_only)
 
         with check_numeric_only_deprecation(name="median"):
@@ -2019,19 +2057,20 @@ class _GroupBy:
             },
             split_every=split_every,
             split_out=split_out,
-            shuffle_method=shuffle,
+            shuffle_method=shuffle_method,
             sort=self.sort,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
-    def size(self, split_every=None, split_out=1, shuffle=None):
+    def size(self, split_every=None, split_out=1, shuffle_method=None):
         return self._single_agg(
             token="size",
             func=M.size,
             aggfunc=M.sum,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
         )
 
     @derived_from(pd.core.groupby.GroupBy)
@@ -2152,9 +2191,14 @@ class _GroupBy:
             result = result[self._slice]
         return result
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     def first(
-        self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
     ):
         numeric_kwargs = get_numeric_only_kwargs(numeric_only)
         return self._single_agg(
@@ -2162,14 +2206,19 @@ class _GroupBy:
             token="first",
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.GroupBy)
     def last(
-        self, split_every=None, split_out=1, shuffle=None, numeric_only=no_default
+        self,
+        split_every=None,
+        split_out=1,
+        shuffle_method=None,
+        numeric_only=no_default,
     ):
         numeric_kwargs = get_numeric_only_kwargs(numeric_only)
         return self._single_agg(
@@ -2177,7 +2226,7 @@ class _GroupBy:
             func=M.last,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             chunk_kwargs=numeric_kwargs,
             aggregate_kwargs=numeric_kwargs,
         )
@@ -2204,9 +2253,10 @@ class _GroupBy:
             token=token,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @_aggregate_docstring()
     def aggregate(
-        self, arg=None, split_every=None, split_out=1, shuffle=None, **kwargs
+        self, arg=None, split_every=None, split_out=1, shuffle_method=None, **kwargs
     ):
         if split_out is None:
             warnings.warn(
@@ -2215,7 +2265,7 @@ class _GroupBy:
                 category=FutureWarning,
             )
             split_out = 1
-        shuffle = _determine_split_out_shuffle(shuffle, split_out)
+        shuffle_method = _determine_split_out_shuffle(shuffle_method, split_out)
 
         relabeling = None
         columns = None
@@ -2307,13 +2357,13 @@ class _GroupBy:
         # If any of the agg funcs contain a "median", we *must* use the shuffle
         # implementation.
         has_median = any(s[1] in ("median", np.median) for s in spec)
-        if has_median and not shuffle:
+        if has_median and not shuffle_method:
             raise ValueError(
                 "In order to aggregate with 'median', you must use shuffling-based "
                 "aggregation (e.g., shuffle='tasks')"
             )
 
-        if shuffle:
+        if shuffle_method:
             # Shuffle-based aggregation
             #
             # This algorithm is more scalable than a tree reduction
@@ -2344,7 +2394,7 @@ class _GroupBy:
                     token="aggregate",
                     split_every=split_every,
                     split_out=split_out,
-                    shuffle_method=shuffle,
+                    shuffle_method=shuffle_method,
                     sort=self.sort,
                 )
             else:
@@ -2368,7 +2418,7 @@ class _GroupBy:
                     token="aggregate",
                     split_every=split_every,
                     split_out=split_out,
-                    shuffle_method=shuffle,
+                    shuffle_method=shuffle_method,
                     sort=self.sort,
                 )
         else:
@@ -2922,9 +2972,10 @@ class DataFrameGroupBy(_GroupBy):
         post_group_columns = self._meta.count().columns
         return len(set(post_group_columns) - set(numerics.columns)) == 0
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @_aggregate_docstring(based_on="pd.core.groupby.DataFrameGroupBy.aggregate")
     def aggregate(
-        self, arg=None, split_every=None, split_out=1, shuffle=None, **kwargs
+        self, arg=None, split_every=None, split_out=1, shuffle_method=None, **kwargs
     ):
         if arg == "size":
             return self.size()
@@ -2933,18 +2984,21 @@ class DataFrameGroupBy(_GroupBy):
             arg=arg,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             **kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @_aggregate_docstring(based_on="pd.core.groupby.DataFrameGroupBy.agg")
     @numeric_only_not_implemented
-    def agg(self, arg=None, split_every=None, split_out=1, shuffle=None, **kwargs):
+    def agg(
+        self, arg=None, split_every=None, split_out=1, shuffle_method=None, **kwargs
+    ):
         return self.aggregate(
             arg=arg,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             **kwargs,
         )
 
@@ -3012,15 +3066,16 @@ class SeriesGroupBy(_GroupBy):
             sort=self.sort,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @_aggregate_docstring(based_on="pd.core.groupby.SeriesGroupBy.aggregate")
     def aggregate(
-        self, arg=None, split_every=None, split_out=1, shuffle=None, **kwargs
+        self, arg=None, split_every=None, split_out=1, shuffle_method=None, **kwargs
     ):
         result = super().aggregate(
             arg=arg,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             **kwargs,
         )
         if self._slice:
@@ -3038,33 +3093,38 @@ class SeriesGroupBy(_GroupBy):
 
         return result
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @_aggregate_docstring(based_on="pd.core.groupby.SeriesGroupBy.agg")
-    def agg(self, arg=None, split_every=None, split_out=1, shuffle=None, **kwargs):
+    def agg(
+        self, arg=None, split_every=None, split_out=1, shuffle_method=None, **kwargs
+    ):
         return self.aggregate(
             arg=arg,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             **kwargs,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.SeriesGroupBy)
-    def value_counts(self, split_every=None, split_out=1, shuffle=None):
+    def value_counts(self, split_every=None, split_out=1, shuffle_method=None):
         return self._single_agg(
             func=_value_counts,
             token="value_counts",
             aggfunc=_value_counts_aggregate,
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
             # in pandas 2.0, Series returned from value_counts have a name
             # different from original object, but here, column name should
             # still reflect the original object name
             columns=self._meta.apply(pd.Series).name,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.SeriesGroupBy)
-    def unique(self, split_every=None, split_out=1, shuffle=None):
+    def unique(self, split_every=None, split_out=1, shuffle_method=None):
         name = self._meta.obj.name
         return self._single_agg(
             func=M.unique,
@@ -3073,11 +3133,12 @@ class SeriesGroupBy(_GroupBy):
             aggregate_kwargs={"name": name},
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.SeriesGroupBy)
-    def tail(self, n=5, split_every=None, split_out=1, shuffle=None):
+    def tail(self, n=5, split_every=None, split_out=1, shuffle_method=None):
         index_levels = len(self.by) if isinstance(self.by, list) else 1
         return self._single_agg(
             func=_tail_chunk,
@@ -3088,11 +3149,12 @@ class SeriesGroupBy(_GroupBy):
             aggregate_kwargs={"n": n, "index_levels": index_levels},
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
         )
 
+    @_deprecated_kwarg("shuffle", "shuffle_method")
     @derived_from(pd.core.groupby.SeriesGroupBy)
-    def head(self, n=5, split_every=None, split_out=1, shuffle=None):
+    def head(self, n=5, split_every=None, split_out=1, shuffle_method=None):
         index_levels = len(self.by) if isinstance(self.by, list) else 1
         return self._single_agg(
             func=_head_chunk,
@@ -3103,7 +3165,7 @@ class SeriesGroupBy(_GroupBy):
             aggregate_kwargs={"n": n, "index_levels": index_levels},
             split_every=split_every,
             split_out=split_out,
-            shuffle=shuffle,
+            shuffle_method=shuffle_method,
         )
 
 


Test patch:
diff --git a/.github/workflows/test-report.yaml b/.github/workflows/test-report.yaml
new file mode 100644
index 000000000..0583aec7b
--- /dev/null
+++ b/.github/workflows/test-report.yaml
@@ -0,0 +1,67 @@
+name: Test Report
+
+on:
+  schedule:
+    # Run 2h after the daily tests.yaml
+    - cron: "0 8,20 * * *"
+  workflow_dispatch:
+
+permissions:
+  contents: write
+
+jobs:
+  test-report:
+    name: Test Report
+    # Do not run the report job on forks
+    if: github.repository == 'dask/dask' || github.event_name == 'workflow_dispatch'
+    runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ github.token }}
+    defaults:
+      run:
+        shell: bash -l {0}
+    steps:
+      - uses: actions/checkout@v4.1.1
+        with:
+          repository: dask/distributed
+
+      - name: Setup Conda Environment
+        uses: conda-incubator/setup-miniconda@v3.0.1
+        with:
+          miniforge-variant: Mambaforge
+          miniforge-version: latest
+          condarc-file: continuous_integration/condarc
+          use-mamba: true
+          # Note: this file is in the dask/distributed repo
+          environment-file: continuous_integration/scripts/test-report-environment.yml
+          activate-environment: dask
+
+      - name: Show conda options
+        run: conda config --show
+
+      - name: mamba list
+        run: mamba list
+
+      - uses: actions/cache@v3
+        id: cache
+        with:
+          # Suffix is depending on the backend / OS. Let's be agnostic here
+          # See https://docs.python.org/3/library/shelve.html#shelve.open
+          path: |
+            test_report*
+            !test_report.html
+          # Note: these files are in the dask/distributed repository
+          key: ${{ hashFiles('continuous_integration/scripts/test_report*') }}
+
+      - name: Generate report
+        run: |
+          python continuous_integration/scripts/test_report.py --repo dask/dask --max-days 90 --max-runs 30 --nfails 1 -o test_report.html
+          python continuous_integration/scripts/test_report.py --repo dask/dask --max-days 7 --max-runs 30 --nfails 2 -o test_short_report.html --title "Test Short Report"
+          mkdir deploy
+          mv test_report.html test_short_report.html deploy/
+
+      - name: Deploy 🚀
+        uses: JamesIves/github-pages-deploy-action@v4.5.0
+        with:
+          branch: gh-pages
+          folder: deploy
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index bae4badda..6d9d9ff7e 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -4,6 +4,8 @@ on:
   push:
   pull_request:
   workflow_dispatch:
+  schedule:
+    - cron: "0 6,18 * * *"  
 
 # When this workflow is queued, automatically cancel any previous running
 # or pending jobs from the same branch
diff --git a/dask/dataframe/tests/test_dataframe.py b/dask/dataframe/tests/test_dataframe.py
index 95bb84de2..6f5658211 100644
--- a/dask/dataframe/tests/test_dataframe.py
+++ b/dask/dataframe/tests/test_dataframe.py
@@ -1201,31 +1201,31 @@ def test_align_dataframes():
     assert_eq(actual, expected, check_index=False, check_divisions=False)
 
 
-@pytest.mark.parametrize("shuffle", [None, True])
-def test_drop_duplicates(shuffle):
+@pytest.mark.parametrize("shuffle_method", [None, True])
+def test_drop_duplicates(shuffle_method):
     res = d.drop_duplicates()
-    res2 = d.drop_duplicates(split_every=2, shuffle=shuffle)
+    res2 = d.drop_duplicates(split_every=2, shuffle_method=shuffle_method)
     sol = full.drop_duplicates()
     assert_eq(res, sol)
     assert_eq(res2, sol)
     assert res._name != res2._name
 
     res = d.a.drop_duplicates()
-    res2 = d.a.drop_duplicates(split_every=2, shuffle=shuffle)
+    res2 = d.a.drop_duplicates(split_every=2, shuffle_method=shuffle_method)
     sol = full.a.drop_duplicates()
     assert_eq(res, sol)
     assert_eq(res2, sol)
     assert res._name != res2._name
 
     res = d.index.drop_duplicates()
-    res2 = d.index.drop_duplicates(split_every=2, shuffle=shuffle)
+    res2 = d.index.drop_duplicates(split_every=2, shuffle_method=shuffle_method)
     sol = full.index.drop_duplicates()
     assert_eq(res, sol)
     assert_eq(res2, sol)
 
     _d = d.clear_divisions()
     res = _d.index.drop_duplicates()
-    res2 = _d.index.drop_duplicates(split_every=2, shuffle=shuffle)
+    res2 = _d.index.drop_duplicates(split_every=2, shuffle_method=shuffle_method)
     sol = full.index.drop_duplicates()
     assert_eq(res, sol)
     assert_eq(res2, sol)
diff --git a/dask/dataframe/tests/test_groupby.py b/dask/dataframe/tests/test_groupby.py
index 54dcb59ba..ac9b45189 100644
--- a/dask/dataframe/tests/test_groupby.py
+++ b/dask/dataframe/tests/test_groupby.py
@@ -1094,8 +1094,10 @@ def test_aggregate__single_element_groups(agg_func):
     if spec in {"mean", "var"}:
         expected = expected.astype(float)
 
-    shuffle = {"shuffle": "tasks"} if agg_func == "median" else {}
-    assert_eq(expected, ddf.groupby(["a", "d"]).agg(spec, **shuffle))
+    shuffle_method = (
+        {"shuffle_method": "tasks", "split_out": 2} if agg_func == "median" else {}
+    )
+    assert_eq(expected, ddf.groupby(["a", "d"]).agg(spec, **shuffle_method))
 
 
 def test_aggregate_build_agg_args__reuse_of_intermediates():
@@ -1235,7 +1237,10 @@ def test_shuffle_aggregate(shuffle_method, split_out, split_every):
 
     spec = {"b": "mean", "c": ["min", "max"]}
     result = ddf.groupby(["a", "b"], sort=False).agg(
-        spec, split_out=split_out, split_every=split_every, shuffle=shuffle_method
+        spec,
+        split_out=split_out,
+        split_every=split_every,
+        shuffle_method=shuffle_method,
     )
     expect = pdf.groupby(["a", "b"]).agg(spec)
 
@@ -1317,14 +1322,14 @@ def test_aggregate_median(spec, keys, shuffle_method):
         columns=["c", "b", "a", "d"],
     )
     ddf = dd.from_pandas(pdf, npartitions=10)
-    actual = ddf.groupby(keys).aggregate(spec, shuffle=shuffle_method)
+    actual = ddf.groupby(keys).aggregate(spec, shuffle_method=shuffle_method)
     expected = pdf.groupby(keys).aggregate(spec)
     assert_eq(actual, expected)
 
     with pytest.raises(ValueError, match="must use shuffl"):
-        ddf.groupby(keys).aggregate(spec, shuffle=False)
+        ddf.groupby(keys).aggregate(spec, shuffle_method=False)
     with pytest.raises(ValueError, match="must use shuffl"):
-        ddf.groupby(keys).median(shuffle=False)
+        ddf.groupby(keys).median(shuffle_method=False)
 
 
 @pytest.mark.skipif(DASK_EXPR_ENABLED, reason="deprecated in pandas")
@@ -3314,10 +3319,10 @@ def test_groupby_sort_true_split_out():
 
     with pytest.raises(NotImplementedError):
         # Cannot use sort=True with split_out>1 using non-shuffle-based approach
-        M.sum(ddf.groupby("x", sort=True), shuffle=False, split_out=2)
+        M.sum(ddf.groupby("x", sort=True), shuffle_method=False, split_out=2)
 
     # Can use sort=True with split_out>1 with agg() if shuffle=True
-    ddf.groupby("x", sort=True).agg("sum", split_out=2, shuffle=True)
+    ddf.groupby("x", sort=True).agg("sum", split_out=2, shuffle_method=True)
 
 
 @pytest.mark.parametrize("known_cats", [True, False], ids=["known", "unknown"])
@@ -3405,8 +3410,8 @@ def test_groupby_numeric_only_None_column_name():
 
 @pytest.mark.skipif(DASK_EXPR_ENABLED, reason="Aggregation not supported")
 @pytest.mark.skipif(not PANDAS_GE_140, reason="requires pandas >= 1.4.0")
-@pytest.mark.parametrize("shuffle", [True, False])
-def test_dataframe_named_agg(shuffle):
+@pytest.mark.parametrize("shuffle_method", [True, False])
+def test_dataframe_named_agg(shuffle_method):
     df = pd.DataFrame(
         {
             "a": [1, 1, 2, 2],
@@ -3421,7 +3426,7 @@ def test_dataframe_named_agg(shuffle):
         y=pd.NamedAgg("c", aggfunc=partial(np.std, ddof=1)),
     )
     actual = ddf.groupby("a").agg(
-        shuffle=shuffle,
+        shuffle_method=shuffle_method,
         x=pd.NamedAgg("b", aggfunc="sum"),
         y=pd.NamedAgg("c", aggfunc=partial(np.std, ddof=1)),
     )
@@ -3430,9 +3435,9 @@ def test_dataframe_named_agg(shuffle):
 
 @pytest.mark.skipif(DASK_EXPR_ENABLED, reason="Aggregation not supported")
 @pytest.mark.skipif(not PANDAS_GE_140, reason="requires pandas >= 1.4.0")
-@pytest.mark.parametrize("shuffle", [True, False])
+@pytest.mark.parametrize("shuffle_method", [True, False])
 @pytest.mark.parametrize("agg", ["count", "mean", partial(np.var, ddof=1)])
-def test_series_named_agg(shuffle, agg):
+def test_series_named_agg(shuffle_method, agg):
     df = pd.DataFrame(
         {
             "a": [5, 4, 3, 5, 4, 2, 3, 2],
@@ -3442,7 +3447,7 @@ def test_series_named_agg(shuffle, agg):
     ddf = dd.from_pandas(df, npartitions=2)
 
     expected = df.groupby("a").b.agg(c=agg, d="sum")
-    actual = ddf.groupby("a").b.agg(shuffle=shuffle, c=agg, d="sum")
+    actual = ddf.groupby("a").b.agg(shuffle_method=shuffle_method, c=agg, d="sum")
     assert_eq(expected, actual)
 
 
@@ -3832,3 +3837,47 @@ def test_groupby_var_dropna_observed(dropna, observed, func):
     dd_result = getattr(ddf.groupby("b", observed=observed, dropna=dropna), func)()
     pdf_result = getattr(df.groupby("b", observed=observed, dropna=dropna), func)()
     assert_eq(dd_result, pdf_result)
+
+
+@pytest.mark.parametrize(
+    "method",
+    (
+        "sum",
+        "prod",
+        "min",
+        "max",
+        "idxmin",
+        "idxmax",
+        "count",
+        "mean",
+        "median",
+        "size",
+        "first",
+        "last",
+        "aggregate",
+        "agg",
+        "value_counts",
+        "tail",
+        "head",
+    ),
+)
+def test_parameter_shuffle_renamed_to_shuffle_method_deprecation(method):
+    df = pd.DataFrame(
+        {
+            "a": np.random.randint(0, 10, size=100),
+            "b": np.random.randint(0, 20, size=100),
+        }
+    )
+    ddf = dd.from_pandas(df, npartitions=2)
+
+    args = ()
+    if method.startswith("agg"):
+        args = ("sum",)
+
+    group_obj = ddf.groupby("a")
+    if method in ("value_counts", "tail", "head"):  # SeriesGroupBy deprecated methods
+        group_obj = group_obj.b
+
+    msg = "the 'shuffle' keyword is deprecated, use 'shuffle_method' instead."
+    with pytest.warns(FutureWarning, match=msg):
+        getattr(group_obj, method)(*args, shuffle="tasks")