Repository: modin-project/modin

Issue:
REFACTOR: Add error checking at API layer for df.diff()
this is part of https://github.com/ponder-org/modin-public/commit/2402cc17ca88e38066830a509d3e5a5bee02ab31


Discussion:

Resolving patch:
diff --git a/modin/core/storage_formats/base/query_compiler.py b/modin/core/storage_formats/base/query_compiler.py
--- a/modin/core/storage_formats/base/query_compiler.py
+++ b/modin/core/storage_formats/base/query_compiler.py
@@ -2109,14 +2109,13 @@ def cumprod(self, fold_axis, **kwargs):  # noqa: PR02
         return DataFrameDefault.register(pandas.DataFrame.cumprod)(self, **kwargs)
 
     @doc_utils.add_refer_to("DataFrame.diff")
-    def diff(self, fold_axis, **kwargs):  # noqa: PR02
+    def diff(self, **kwargs):  # noqa: PR02
         """
         First discrete difference of element.
 
         Parameters
         ----------
         periods : int
-        fold_axis : {0, 1}
         **kwargs : dict
             Serves the compatibility purpose. Does not affect the result.
 
diff --git a/modin/core/storage_formats/pandas/query_compiler.py b/modin/core/storage_formats/pandas/query_compiler.py
--- a/modin/core/storage_formats/pandas/query_compiler.py
+++ b/modin/core/storage_formats/pandas/query_compiler.py
@@ -2075,7 +2075,10 @@ def describe_builder(df, internal_indices=[]):  # pragma: no cover
     cummin = Fold.register(pandas.DataFrame.cummin)
     cumsum = Fold.register(pandas.DataFrame.cumsum)
     cumprod = Fold.register(pandas.DataFrame.cumprod)
-    diff = Fold.register(pandas.DataFrame.diff)
+    _diff = Fold.register(pandas.DataFrame.diff)
+
+    def diff(self, axis, periods):
+        return self._diff(fold_axis=axis, axis=axis, periods=periods)
 
     def clip(self, lower, upper, **kwargs):
         if isinstance(lower, BaseQueryCompiler):
diff --git a/modin/pandas/base.py b/modin/pandas/base.py
--- a/modin/pandas/base.py
+++ b/modin/pandas/base.py
@@ -1296,11 +1296,18 @@ def diff(self, periods=1, axis=0):  # noqa: PR01, RT01, D200
         """
         First discrete difference of element.
         """
+        # Attempting to match pandas error behavior here
+        if not isinstance(periods, int):
+            raise ValueError(f"periods must be an int. got {type(periods)} instead")
+
+        # Attempting to match pandas error behavior here
+        for dtype in self._get_dtypes():
+            if not is_numeric_dtype(dtype):
+                raise TypeError(f"unsupported operand type for -: got {dtype}")
+
         axis = self._get_axis_number(axis)
         return self.__constructor__(
-            query_compiler=self._query_compiler.diff(
-                fold_axis=axis, axis=axis, periods=periods
-            )
+            query_compiler=self._query_compiler.diff(axis=axis, periods=periods)
         )
 
     def drop(


Test patch:
diff --git a/modin/pandas/test/dataframe/test_window.py b/modin/pandas/test/dataframe/test_window.py
--- a/modin/pandas/test/dataframe/test_window.py
+++ b/modin/pandas/test/dataframe/test_window.py
@@ -92,6 +92,17 @@ def test_diff(axis, periods):
     )
 
 
+def test_diff_error_handling():
+    df = pd.DataFrame([["a", "b", "c"]], columns=["col 0", "col 1", "col 2"])
+    with pytest.raises(
+        ValueError, match="periods must be an int. got <class 'str'> instead"
+    ):
+        df.diff(axis=0, periods="1")
+
+    with pytest.raises(TypeError, match="unsupported operand type for -: got object"):
+        df.diff()
+
+
 @pytest.mark.parametrize("axis", ["rows", "columns"])
 def test_diff_transposed(axis):
     eval_general(