Repository: pandas-dev/pandas
Pull request #57379 (2024-02-12 18:18:43)

Fix numpy-dev CI warnings


Patch:
diff --git a/ci/code_checks.sh b/ci/code_checks.sh
index 9c9cd2cc66..75fb82b1e2 100755
--- a/ci/code_checks.sh
+++ b/ci/code_checks.sh
@@ -137,13 +137,74 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then
         pandas.Interval\
         pandas.Grouper\
         pandas.core.groupby.DataFrameGroupBy.nth\
-        pandas.core.groupby.DataFrameGroupBy.rolling\
         pandas.core.groupby.SeriesGroupBy.nth\
-        pandas.core.groupby.SeriesGroupBy.rolling\
         pandas.core.groupby.DataFrameGroupBy.plot\
         pandas.core.groupby.SeriesGroupBy.plot # There should be no backslash in the final line, please keep this comment in the last ignored function
     RET=$(($RET + $?)) ; echo $MSG "DONE"
 
+    MSG='Partially validate docstrings (SA05)' ;  echo $MSG
+    $BASE_DIR/scripts/validate_docstrings.py --format=actions --errors=SA05 --ignore_functions \
+        pandas.DataFrame.agg\
+        pandas.DataFrame.aggregate\
+        pandas.DataFrame.boxplot\
+        pandas.PeriodIndex.asfreq\
+        pandas.arrays.ArrowStringArray\
+        pandas.arrays.StringArray\
+        pandas.core.groupby.DataFrameGroupBy.first\
+        pandas.core.groupby.DataFrameGroupBy.last\
+        pandas.core.groupby.SeriesGroupBy.first\
+        pandas.core.groupby.SeriesGroupBy.last\
+        pandas.core.resample.Resampler.first\
+        pandas.core.resample.Resampler.last\
+        pandas.core.window.ewm.ExponentialMovingWindow.corr\
+        pandas.core.window.ewm.ExponentialMovingWindow.cov\
+        pandas.core.window.ewm.ExponentialMovingWindow.mean\
+        pandas.core.window.ewm.ExponentialMovingWindow.std\
+        pandas.core.window.ewm.ExponentialMovingWindow.sum\
+        pandas.core.window.ewm.ExponentialMovingWindow.var\
+        pandas.core.window.expanding.Expanding.aggregate\
+        pandas.core.window.expanding.Expanding.apply\
+        pandas.core.window.expanding.Expanding.corr\
+        pandas.core.window.expanding.Expanding.count\
+        pandas.core.window.expanding.Expanding.cov\
+        pandas.core.window.expanding.Expanding.kurt\
+        pandas.core.window.expanding.Expanding.max\
+        pandas.core.window.expanding.Expanding.mean\
+        pandas.core.window.expanding.Expanding.median\
+        pandas.core.window.expanding.Expanding.min\
+        pandas.core.window.expanding.Expanding.quantile\
+        pandas.core.window.expanding.Expanding.rank\
+        pandas.core.window.expanding.Expanding.sem\
+        pandas.core.window.expanding.Expanding.skew\
+        pandas.core.window.expanding.Expanding.std\
+        pandas.core.window.expanding.Expanding.sum\
+        pandas.core.window.expanding.Expanding.var\
+        pandas.core.window.rolling.Rolling.aggregate\
+        pandas.core.window.rolling.Rolling.apply\
+        pandas.core.window.rolling.Rolling.corr\
+        pandas.core.window.rolling.Rolling.count\
+        pandas.core.window.rolling.Rolling.cov\
+        pandas.core.window.rolling.Rolling.kurt\
+        pandas.core.window.rolling.Rolling.max\
+        pandas.core.window.rolling.Rolling.mean\
+        pandas.core.window.rolling.Rolling.median\
+        pandas.core.window.rolling.Rolling.min\
+        pandas.core.window.rolling.Rolling.quantile\
+        pandas.core.window.rolling.Rolling.rank\
+        pandas.core.window.rolling.Rolling.sem\
+        pandas.core.window.rolling.Rolling.skew\
+        pandas.core.window.rolling.Rolling.std\
+        pandas.core.window.rolling.Rolling.sum\
+        pandas.core.window.rolling.Rolling.var\
+        pandas.core.window.rolling.Window.mean\
+        pandas.core.window.rolling.Window.std\
+        pandas.core.window.rolling.Window.sum\
+        pandas.core.window.rolling.Window.var\
+        pandas.plotting.bootstrap_plot\
+        pandas.plotting.boxplot\
+        pandas.plotting.radviz # There should be no backslash in the final line, please keep this comment in the last ignored function
+    RET=$(($RET + $?)) ; echo $MSG "DONE"
+
 fi
 
 ### DOCUMENTATION NOTEBOOKS ###
diff --git a/doc/source/whatsnew/v2.2.1.rst b/doc/source/whatsnew/v2.2.1.rst
index eb6e50c1be..94e26ff6aa 100644
--- a/doc/source/whatsnew/v2.2.1.rst
+++ b/doc/source/whatsnew/v2.2.1.rst
@@ -17,6 +17,7 @@ Fixed regressions
 - Fixed performance regression in :meth:`Series.combine_first` (:issue:`55845`)
 - Fixed regression in :func:`concat` changing long-standing behavior that always sorted the non-concatenation axis when the axis was a :class:`DatetimeIndex` (:issue:`57006`)
 - Fixed regression in :func:`merge_ordered` raising ``TypeError`` for ``fill_method="ffill"`` and ``how="left"`` (:issue:`57010`)
+- Fixed regression in :func:`pandas.testing.assert_series_equal` defaulting to ``check_exact=True`` when checking the :class:`Index` (:issue:`57067`)
 - Fixed regression in :func:`wide_to_long` raising an ``AttributeError`` for string columns (:issue:`57066`)
 - Fixed regression in :meth:`.DataFrameGroupBy.idxmin`, :meth:`.DataFrameGroupBy.idxmax`, :meth:`.SeriesGroupBy.idxmin`, :meth:`.SeriesGroupBy.idxmax` ignoring the ``skipna`` argument (:issue:`57040`)
 - Fixed regression in :meth:`.DataFrameGroupBy.idxmin`, :meth:`.DataFrameGroupBy.idxmax`, :meth:`.SeriesGroupBy.idxmin`, :meth:`.SeriesGroupBy.idxmax` where values containing the minimum or maximum value for the dtype could produce incorrect results (:issue:`57040`)
@@ -24,6 +25,7 @@ Fixed regressions
 - Fixed regression in :meth:`DataFrame.groupby` raising ``ValueError`` when grouping by a :class:`Series` in some cases (:issue:`57276`)
 - Fixed regression in :meth:`DataFrame.loc` raising ``IndexError`` for non-unique, masked dtype indexes where result has more than 10,000 rows (:issue:`57027`)
 - Fixed regression in :meth:`DataFrame.merge` raising ``ValueError`` for certain types of 3rd-party extension arrays (:issue:`57316`)
+- Fixed regression in :meth:`DataFrame.shift` raising ``AssertionError`` for ``axis=1`` and empty :class:`DataFrame` (:issue:`57301`)
 - Fixed regression in :meth:`DataFrame.sort_index` not producing a stable sort for a index with duplicates (:issue:`57151`)
 - Fixed regression in :meth:`DataFrame.to_dict` with ``orient='list'`` and datetime or timedelta types returning integers (:issue:`54824`)
 - Fixed regression in :meth:`DataFrame.to_json` converting nullable integers to floats (:issue:`57224`)
diff --git a/pandas/_libs/src/vendored/ujson/python/objToJSON.c b/pandas/_libs/src/vendored/ujson/python/objToJSON.c
index 8bba95dd45..74ca8ead3d 100644
--- a/pandas/_libs/src/vendored/ujson/python/objToJSON.c
+++ b/pandas/_libs/src/vendored/ujson/python/objToJSON.c
@@ -447,8 +447,15 @@ static void NpyArrPassThru_iterEnd(JSOBJ obj, JSONTypeContext *tc) {
   npyarr->curdim--;
   npyarr->dataptr -= npyarr->stride * npyarr->index[npyarr->stridedim];
   npyarr->stridedim -= npyarr->inc;
-  npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim);
-  npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim);
+
+  if (!PyArray_Check(npyarr->array)) {
+    PyErr_SetString(PyExc_TypeError,
+                    "NpyArrayPassThru_iterEnd received a non-array object");
+    return;
+  }
+  const PyArrayObject *arrayobj = (const PyArrayObject *)npyarr->array;
+  npyarr->dim = PyArray_DIM(arrayobj, npyarr->stridedim);
+  npyarr->stride = PyArray_STRIDE(arrayobj, npyarr->stridedim);
   npyarr->dataptr += npyarr->stride;
 
   NpyArr_freeItemValue(obj, tc);
@@ -467,12 +474,19 @@ static int NpyArr_iterNextItem(JSOBJ obj, JSONTypeContext *tc) {
 
   NpyArr_freeItemValue(obj, tc);
 
-  if (PyArray_ISDATETIME(npyarr->array)) {
+  if (!PyArray_Check(npyarr->array)) {
+    PyErr_SetString(PyExc_TypeError,
+                    "NpyArr_iterNextItem received a non-array object");
+    return 0;
+  }
+  PyArrayObject *arrayobj = (PyArrayObject *)npyarr->array;
+
+  if (PyArray_ISDATETIME(arrayobj)) {
     GET_TC(tc)->itemValue = obj;
     Py_INCREF(obj);
-    ((PyObjectEncoder *)tc->encoder)->npyType = PyArray_TYPE(npyarr->array);
+    ((PyObjectEncoder *)tc->encoder)->npyType = PyArray_TYPE(arrayobj);
     // Also write the resolution (unit) of the ndarray
-    PyArray_Descr *dtype = PyArray_DESCR(npyarr->array);
+    PyArray_Descr *dtype = PyArray_DESCR(arrayobj);
     ((PyObjectEncoder *)tc->encoder)->valueUnit =
         get_datetime_metadata_from_dtype(dtype).base;
     ((PyObjectEncoder *)tc->encoder)->npyValue = npyarr->dataptr;
@@ -505,8 +519,15 @@ static int NpyArr_iterNext(JSOBJ _obj, JSONTypeContext *tc) {
 
   npyarr->curdim++;
   npyarr->stridedim += npyarr->inc;
-  npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim);
-  npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim);
+  if (!PyArray_Check(npyarr->array)) {
+    PyErr_SetString(PyExc_TypeError,
+                    "NpyArr_iterNext received a non-array object");
+    return 0;
+  }
+  const PyArrayObject *arrayobj = (const PyArrayObject *)npyarr->array;
+
+  npyarr->dim = PyArray_DIM(arrayobj, npyarr->stridedim);
+  npyarr->stride = PyArray_STRIDE(arrayobj, npyarr->stridedim);
   npyarr->index[npyarr->stridedim] = 0;
 
   ((PyObjectEncoder *)tc->encoder)->npyCtxtPassthru = npyarr;
@@ -1610,7 +1631,14 @@ ISITERABLE:
       if (!values) {
         goto INVALID;
       }
-      pc->columnLabelsLen = PyArray_DIM(pc->newObj, 0);
+
+      if (!PyArray_Check(pc->newObj)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Object_beginTypeContext received a non-array object");
+        goto INVALID;
+      }
+      const PyArrayObject *arrayobj = (const PyArrayObject *)pc->newObj;
+      pc->columnLabelsLen = PyArray_DIM(arrayobj, 0);
       pc->columnLabels = NpyArr_encodeLabels((PyArrayObject *)values, enc,
                                              pc->columnLabelsLen);
       if (!pc->columnLabels) {
diff --git a/pandas/core/base.py b/pandas/core/base.py
index 7a31023173..2858aef544 100644
--- a/pandas/core/base.py
+++ b/pandas/core/base.py
@@ -18,8 +18,6 @@ import warnings
 
 import numpy as np
 
-from pandas._config import using_copy_on_write
-
 from pandas._libs import lib
 from pandas._typing import (
     AxisInt,
@@ -661,10 +659,10 @@ class IndexOpsMixin(OpsMixin):
 
         result = np.asarray(values, dtype=dtype)
 
-        if (copy and not fillna) or (not copy and using_copy_on_write()):
+        if (copy and not fillna) or not copy:
             if np.shares_memory(self._values[:2], result[:2]):
                 # Take slices to improve performance of check
-                if using_copy_on_write() and not copy:
+                if not copy:
                     result = result.view()
                     result.flags.writeable = False
                 else:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index a62c3c8cd5..0b9d9eba80 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -5545,6 +5545,9 @@ class DataFrame(NDFrame, OpsMixin):
             )
             fill_value = lib.no_default
 
+        if self.empty:
+            return self.copy()
+
         axis = self._get_axis_number(axis)
 
         if is_list_like(periods):
diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py
index b1dfabcf0c..1be1cdfcd0 100644
--- a/pandas/core/groupby/groupby.py
+++ b/pandas/core/groupby/groupby.py
@@ -47,6 +47,7 @@ from pandas._typing import (
     DtypeObj,
     FillnaOptions,
     IndexLabel,
+    IntervalClosedType,
     NDFrameT,
     PositionalIndexer,
     RandomState,
@@ -139,6 +140,7 @@ from pandas.core.util.numba_ import (
 )
 
 if TYPE_CHECKING:
+    from pandas._libs.tslibs import BaseOffset
     from pandas._typing import (
         Any,
         Concatenate,
@@ -147,6 +149,7 @@ if TYPE_CHECKING:
         T,
     )
 
+    from pandas.core.indexers.objects import BaseIndexer
     from pandas.core.resample import Resampler
     from pandas.core.window import (
         ExpandingGroupby,
@@ -3616,7 +3619,16 @@ class GroupBy(BaseGroupBy[NDFrameT]):
         )
 
     @final
-    def rolling(self, *args, **kwargs) -> RollingGroupby:
+    def rolling(
+        self,
+        window: int | datetime.timedelta | str | BaseOffset | BaseIndexer,
+        min_periods: int | None = None,
+        center: bool = False,
+        win_type: str | None = None,
+        on: str | None = None,
+        closed: IntervalClosedType | None = None,
+        method: str = "single",
+    ) -> RollingGroupby:
         """
         Return a rolling grouper, providing rolling functionality per group.
 
@@ -3746,10 +3758,15 @@ class GroupBy(BaseGroupBy[NDFrameT]):
 
         return RollingGroupby(
             self._selected_obj,
-            *args,
+            window=window,
+            min_periods=min_periods,
+            center=center,
+            win_type=win_type,
+            on=on,
+            closed=closed,
+            method=method,
             _grouper=self._grouper,
             _as_index=self.as_index,
-            **kwargs,
         )
 
     @final
diff --git a/pandas/core/indexes/api.py b/pandas/core/indexes/api.py
index 15292953e7..a8887a21af 100644
--- a/pandas/core/indexes/api.py
+++ b/pandas/core/indexes/api.py
@@ -74,7 +74,6 @@ def get_objs_combined_axis(
     intersect: bool = False,
     axis: Axis = 0,
     sort: bool = True,
-    copy: bool = False,
 ) -> Index:
     """
     Extract combined index: return intersection or union (depending on the
@@ -92,15 +91,13 @@ def get_objs_combined_axis(
         The axis to extract indexes from.
     sort : bool, default True
         Whether the result index should come out sorted or not.
-    copy : bool, default False
-        If True, return a copy of the combined index.
 
     Returns
     -------
     Index
     """
     obs_idxes = [obj._get_axis(axis) for obj in objs]
-    return _get_combined_index(obs_idxes, intersect=intersect, sort=sort, copy=copy)
+    return _get_combined_index(obs_idxes, intersect=intersect, sort=sort)
 
 
 def _get_distinct_objs(objs: list[Index]) -> list[Index]:
@@ -121,7 +118,6 @@ def _get_combined_index(
     indexes: list[Index],
     intersect: bool = False,
     sort: bool = False,
-    copy: bool = False,
 ) -> Index:
     """
     Return the union or intersection of indexes.
@@ -135,8 +131,6 @@ def _get_combined_index(
         calculate the union.
     sort : bool, default False
         Whether the result index should come out sorted or not.
-    copy : bool, default False
-        If True, return a copy of the combined index.
 
     Returns
     -------
@@ -158,10 +152,6 @@ def _get_combined_index(
 
     if sort:
         index = safe_sort_index(index)
-    # GH 29879
-    if copy:
-        index = index.copy()
-
     return index
 
 
diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
index e2b3666ea9..d9f545969d 100644
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -22,7 +22,6 @@ import numpy as np
 
 from pandas._config import (
     get_option,
-    using_copy_on_write,
     using_pyarrow_string_dtype,
 )
 
@@ -1633,7 +1632,7 @@ class Index(IndexOpsMixin, PandasObject):
 
         if name is lib.no_default:
             name = self._get_level_names()
-        result = DataFrame({name: self}, copy=not using_copy_on_write())
+        result = DataFrame({name: self}, copy=False)
 
         if index:
             result.index = self
@@ -4773,13 +4772,11 @@ class Index(IndexOpsMixin, PandasObject):
         [(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]]
         Length: 5, dtype: interval[int64, right]
         """
-        if using_copy_on_write():
-            data = self._data
-            if isinstance(data, np.ndarray):
-                data = data.view()
-                data.flags.writeable = False
-            return data
-        return self._data
+        data = self._data
+        if isinstance(data, np.ndarray):
+            data = data.view()
+            data.flags.writeable = False
+        return data
 
     @cache_readonly
     @doc(IndexOpsMixin.array)
diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py
index 17a8bcd702..8242dc49e6 100644
--- a/pandas/core/indexes/datetimelike.py
+++ b/pandas/core/indexes/datetimelike.py
@@ -16,8 +16,6 @@ from typing import (
 
 import numpy as np
 
-from pandas._config import using_copy_on_write
-
 from pandas._libs import (
     NaT,
     Timedelta,
@@ -454,9 +452,8 @@ class DatetimeTimedeltaMixin(DatetimeIndexOpsMixin, ABC):
     def values(self) -> np.ndarray:
         # NB: For Datetime64TZ this is lossy
         data = self._data._ndarray
-        if using_copy_on_write():
-            data = data.view()
-            data.flags.writeable = False
+        data = data.view()
+        data.flags.writeable = False
         return data
 
     @doc(DatetimeIndexOpsMixin.shift)
diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py
index 7d31467c6f..c6759a9f54 100644
--- a/pandas/core/indexing.py
+++ b/pandas/core/indexing.py
@@ -13,8 +13,6 @@ import warnings
 
 import numpy as np
 
-from pandas._config import using_copy_on_write
-
 from pandas._libs.indexing import NDFrameIndexerBase
 from pandas._libs.lib import item_from_zerodim
 from pandas.compat import PYPY
@@ -894,7 +892,7 @@ class _LocationIndexer(NDFrameIndexerBase):
 
     @final
     def __setitem__(self, key, value) -> None:
-        if not PYPY and using_copy_on_write():
+        if not PYPY:
             if sys.getrefcount(self.obj) <= 2:
                 warnings.warn(
                     _chained_assignment_msg, ChainedAssignmentError, stacklevel=2
@@ -2107,7 +2105,7 @@ class _iLocIndexer(_LocationIndexer):
                         tuple(sub_indexer),
                         value[item],
                         multiindex_indexer,
-                        using_cow=using_copy_on_write(),
+                        using_cow=True,
                     )
                 else:
                     val = np.nan
diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py
index d47cb3f40f..88323e5304 100644
--- a/pandas/core/reshape/concat.py
+++ b/pandas/core/reshape/concat.py
@@ -15,8 +15,6 @@ import warnings
 
 import numpy as np
 
-from pandas._config import using_copy_on_write
-
 from pandas.util._decorators import cache_readonly
 from pandas.util._exceptions import find_stack_level
 
@@ -370,13 +368,6 @@ def concat(
     0   1   2
     1   3   4
     """
-    if copy is None:
-        if using_copy_on_write():
-            copy = False
-        else:
-            copy = True
-    elif copy and using_copy_on_write():
-        copy = False
 
     op = _Concatenator(
         objs,
@@ -387,7 +378,6 @@ def concat(
         levels=levels,
         names=names,
         verify_integrity=verify_integrity,
-        copy=copy,
         sort=sort,
     )
 
@@ -411,7 +401,6 @@ class _Concatenator:
         names: list[HashableT] | None = None,
         ignore_index: bool = False,
         verify_integrity: bool = False,
-        copy: bool = True,
         sort: bool = False,
     ) -> None:
         if isinstance(objs, (ABCSeries, ABCDataFrame, str)):
@@ -439,7 +428,6 @@ class _Concatenator:
 
         self.ignore_index = ignore_index
         self.verify_integrity = verify_integrity
-        self.copy = copy
 
         objs, keys = self._clean_keys_and_objs(objs, keys)
 
@@ -656,7 +644,7 @@ class _Concatenator:
                 cons = sample._constructor_expanddim
 
                 index, columns = self.new_axes
-                df = cons(data, index=index, copy=self.copy)
+                df = cons(data, index=index, copy=False)
                 df.columns = columns
                 return df.__finalize__(self, method="concat")
 
@@ -681,10 +669,8 @@ class _Concatenator:
                 mgrs_indexers.append((obj._mgr, indexers))
 
             new_data = concatenate_managers(
-                mgrs_indexers, self.new_axes, concat_axis=self.bm_axis, copy=self.copy
+                mgrs_indexers, self.new_axes, concat_axis=self.bm_axis, copy=False
             )
-            if not self.copy and not using_copy_on_write():
-                new_data._consolidate_inplace()
 
             out = sample._constructor_from_mgr(new_data, axes=new_data.axes)
             return out.__finalize__(self, method="concat")
@@ -710,7 +696,6 @@ class _Concatenator:
             axis=data_axis,
             intersect=self.intersect,
             sort=self.sort,
-            copy=self.copy,
         )
 
     @cache_readonly
diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py
index 07920eb175..d9dc5b41a8 100644
--- a/pandas/io/parsers/readers.py
+++ b/pandas/io/parsers/readers.py
@@ -26,8 +26,6 @@ import warnings
 
 import numpy as np
 
-from pandas._config import using_copy_on_write
-
 from pandas._libs import lib
 from pandas._libs.parsers import STR_NA_VALUES
 from pandas.errors import (
@@ -1967,7 +1965,7 @@ class TextFileReader(abc.Iterator):
                 new_col_dict,
                 columns=columns,
                 index=index,
-                copy=not using_copy_on_write(),
+                copy=False,
             )
 
             self._currow += new_rows
diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py
index 1e11a9783f..97b9b905df 100644
--- a/pandas/io/pytables.py
+++ b/pandas/io/pytables.py
@@ -30,7 +30,6 @@ import numpy as np
 from pandas._config import (
     config,
     get_option,
-    using_copy_on_write,
     using_pyarrow_string_dtype,
 )
 
@@ -3294,13 +3293,8 @@ class BlockManagerFixed(GenericFixed):
             dfs.append(df)
 
         if len(dfs) > 0:
-            out = concat(dfs, axis=1, copy=True)
-            if using_copy_on_write():
-                # with CoW, concat ignores the copy keyword. Here, we still want
-                # to copy to enforce optimized column-major layout
-                out = out.copy()
-            out = out.reindex(columns=items, copy=False)
-            return out
+            out = concat(dfs, axis=1).copy()
+            return out.reindex(columns=items, copy=False)
 
         return DataFrame(columns=axes[0], index=axes[1])
 


Test patch:
diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py
index 4aea85d50c..3aacd3099c 100644
--- a/pandas/_testing/asserters.py
+++ b/pandas/_testing/asserters.py
@@ -902,6 +902,7 @@ def assert_series_equal(
     >>> tm.assert_series_equal(a, b)
     """
     __tracebackhide__ = True
+    check_exact_index = False if check_exact is lib.no_default else check_exact
     if (
         check_exact is lib.no_default
         and rtol is lib.no_default
@@ -944,7 +945,7 @@ def assert_series_equal(
             right.index,
             exact=check_index_type,
             check_names=check_names,
-            check_exact=check_exact,
+            check_exact=check_exact_index,
             check_categorical=check_categorical,
             check_order=not check_like,
             rtol=rtol,
diff --git a/pandas/tests/frame/methods/test_shift.py b/pandas/tests/frame/methods/test_shift.py
index c477c9c185..5bcfaf8b19 100644
--- a/pandas/tests/frame/methods/test_shift.py
+++ b/pandas/tests/frame/methods/test_shift.py
@@ -751,3 +751,9 @@ class TestDataFrameShift:
         msg = "Cannot specify `suffix` if `periods` is an int."
         with pytest.raises(ValueError, match=msg):
             df.shift(1, suffix="fails")
+
+    def test_shift_axis_one_empty(self):
+        # GH#57301
+        df = DataFrame()
+        result = df.shift(1, axis=1)
+        tm.assert_frame_equal(result, df)
diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py
index db45067162..2d06c2f258 100644
--- a/pandas/tests/groupby/test_groupby.py
+++ b/pandas/tests/groupby/test_groupby.py
@@ -2423,7 +2423,9 @@ def test_rolling_wrong_param_min_period():
     test_df = DataFrame([name_l, val_l]).T
     test_df.columns = ["name", "val"]
 
-    result_error_msg = r"__init__\(\) got an unexpected keyword argument 'min_period'"
+    result_error_msg = (
+        r"^[a-zA-Z._]*\(\) got an unexpected keyword argument 'min_period'$"
+    )
     with pytest.raises(TypeError, match=result_error_msg):
         test_df.groupby("name")["val"].rolling(window=2, min_period=1).sum()
 
diff --git a/pandas/tests/util/test_assert_series_equal.py b/pandas/tests/util/test_assert_series_equal.py
index 4c695190c1..0b3bc07c17 100644
--- a/pandas/tests/util/test_assert_series_equal.py
+++ b/pandas/tests/util/test_assert_series_equal.py
@@ -473,3 +473,11 @@ def test_assert_series_equal_int_tol():
     tm.assert_extension_array_equal(
         left.astype("Int64").values, right.astype("Int64").values, rtol=1.5
     )
+
+
+def test_assert_series_equal_index_exact_default():
+    # GH#57067
+    ser1 = Series(np.zeros(6, dtype=int), [0, 0.2, 0.4, 0.6, 0.8, 1])
+    ser2 = Series(np.zeros(6, dtype=int), np.linspace(0, 1, 6))
+    tm.assert_series_equal(ser1, ser2)
+    tm.assert_frame_equal(ser1.to_frame(), ser2.to_frame())