Repository: modin-project/modin

Issue:
Inplace operations in Dask alter the Future
### Describe the problem
<!-- Describe the problem clearly here. -->
Previously, we assumed that the futures objects that were operated on were immutable. This is an assumption that was safe with Ray, but not with Dask.

### Source code / logs
e.g.

https://github.com/modin-project/modin/blob/32563c8a2c7b104c84ebf2c870a7be39a37fceae/modin/engines/base/frame/data.py#L244
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->



Discussion:
Discovered as a test failure in #957.

Resolving patch:
diff --git a/modin/backends/pandas/query_compiler.py b/modin/backends/pandas/query_compiler.py
--- a/modin/backends/pandas/query_compiler.py
+++ b/modin/backends/pandas/query_compiler.py
@@ -479,8 +479,9 @@ def first_valid_index(self):
         """
 
         def first_valid_index_builder(df):
-            df.index = pandas.RangeIndex(len(df.index))
-            return df.apply(lambda df: df.first_valid_index())
+            return df.set_axis(
+                pandas.RangeIndex(len(df.index)), axis="index", inplace=False
+            ).apply(lambda df: df.first_valid_index())
 
         # We get the minimum from each column, then take the min of that to get
         # first_valid_index. The `to_pandas()` here is just for a single value and
@@ -503,8 +504,9 @@ def last_valid_index(self):
         """
 
         def last_valid_index_builder(df):
-            df.index = pandas.RangeIndex(len(df.index))
-            return df.apply(lambda df: df.last_valid_index())
+            return df.set_axis(
+                pandas.RangeIndex(len(df.index)), axis="index", inplace=False
+            ).apply(lambda df: df.last_valid_index())
 
         # We get the maximum from each column, then take the max of that to get
         # last_valid_index. The `to_pandas()` here is just for a single value and
@@ -892,24 +894,17 @@ def setitem(self, axis, key, value):
         """
 
         def setitem_builder(df, internal_indices=[]):
-            def _setitem():
-                if len(internal_indices) == 1:
-                    if axis == 0:
-                        df[df.columns[internal_indices[0]]] = value
-                    else:
-                        df.iloc[internal_indices[0]] = value
+            df = df.copy()
+            if len(internal_indices) == 1:
+                if axis == 0:
+                    df[df.columns[internal_indices[0]]] = value
                 else:
-                    if axis == 0:
-                        df[df.columns[internal_indices]] = value
-                    else:
-                        df.iloc[internal_indices] = value
-
-            try:
-                _setitem()
-            except ValueError:
-                # TODO: This is a workaround for a pyarrow serialization issue
-                df = df.copy()
-                _setitem()
+                    df.iloc[internal_indices[0]] = value
+            else:
+                if axis == 0:
+                    df[df.columns[internal_indices]] = value
+                else:
+                    df.iloc[internal_indices] = value
             return df
 
         if isinstance(value, type(self)):
diff --git a/modin/engines/base/frame/data.py b/modin/engines/base/frame/data.py
--- a/modin/engines/base/frame/data.py
+++ b/modin/engines/base/frame/data.py
@@ -241,8 +241,9 @@ def _apply_index_objs(self, axis=None):
         if axis is None:
 
             def apply_idx_objs(df, idx, cols):
-                df.index, df.columns = idx, cols
-                return df
+                return df.set_axis(idx, axis="index", inplace=False).set_axis(
+                    cols, axis="columns", inplace=False
+                )
 
             self._partitions = np.array(
                 [
@@ -264,8 +265,7 @@ def apply_idx_objs(df, idx, cols):
         elif axis == 0:
 
             def apply_idx_objs(df, idx):
-                df.index = idx
-                return df
+                return df.set_axis(idx, axis="index", inplace=False)
 
             self._partitions = np.array(
                 [
@@ -284,8 +284,7 @@ def apply_idx_objs(df, idx):
         elif axis == 1:
 
             def apply_idx_objs(df, cols):
-                df.columns = cols
-                return df
+                return df.set_axis(cols, axis="columns", inplace=False)
 
             self._partitions = np.array(
                 [


Test patch: