Repository: modin-project/modin

Issue:
'update' function implementation
<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
<!-- Describe the problem clearly here. -->
While working with @devin-petersohn on implementing a progress bar, it seemed like the implementation of df.update() or other in-place operations might want to use different functions or names. Currently the progress bar says computation is being performed by a "caller" function.

### Source code / logs
<!-- 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. -->
![image](https://user-images.githubusercontent.com/31913344/93410125-43176b80-f84d-11ea-9e78-88f7bdb08486.png)



Discussion:
Hi @noah-kuo , thanks for reporting!
Looks like the progress bar says correctly because [this function](https://github.com/modin-project/modin/blob/master/modin/backends/pandas/query_compiler.py#L141) is being performed if we call df.update() or series.update(). You suppose that the progress bar should say computation is being performed by a "update" function?
Yes @YarShev, it would be better to show `update`, which is the pandas API that was called. We wrap the `pandas.DataFrame.update` in the `caller` function because it is inplace and Modin does not allow inplace updates.

I am not sure that there is a nice solution to this problem.
@devin-petersohn , okay, I will take a look on this.
We could do it this way ([link](https://github.com/YarShev/modin/commit/80138ab421bd906fd43eda35908abfc0a3d2b66a)). @devin-petersohn , what do you think?
#2092 
Left a comment on your commit @YarShev 
I have created the PR to simplify discussion. Current comments:
Devin: what about `func.__name__` instead?
Yaroslav: There are some cases when we pass `lambda` as a parameter `func` to the `copy_df_for_func`. `func.__name__` will be `lambda` in that case. We already have the such example for `series_update`. Perhaps, we will worth adding some docstring on parameter `func_name` in order to facilitate better understanding of other people what is `func_name` needed for. What do you think?

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
@@ -123,7 +123,7 @@ def dt_op_builder(df, *args, **kwargs):
     return dt_op_builder
 
 
-def copy_df_for_func(func):
+def copy_df_for_func(func, display_name: str = None):
     """
     Create a function that copies the dataframe, likely because `func` is inplace.
 
@@ -131,6 +131,8 @@ def copy_df_for_func(func):
     ----------
     func : callable
         The function, usually updates a dataframe inplace.
+    display_name : str, optional
+        The function's name, which is displayed by progress bar.
 
     Returns
     -------
@@ -143,6 +145,8 @@ def caller(df, *args, **kwargs):
         func(df, *args, **kwargs)
         return df
 
+    if display_name is not None:
+        caller.__name__ = display_name
     return caller
 
 
@@ -332,11 +336,13 @@ def to_numpy(self, **kwargs):
     __rxor__ = BinaryFunction.register(pandas.DataFrame.__rxor__)
     __xor__ = BinaryFunction.register(pandas.DataFrame.__xor__)
     df_update = BinaryFunction.register(
-        copy_df_for_func(pandas.DataFrame.update), join_type="left"
+        copy_df_for_func(pandas.DataFrame.update, display_name="update"),
+        join_type="left",
     )
     series_update = BinaryFunction.register(
         copy_df_for_func(
-            lambda x, y: pandas.Series.update(x.squeeze(axis=1), y.squeeze(axis=1))
+            lambda x, y: pandas.Series.update(x.squeeze(axis=1), y.squeeze(axis=1)),
+            display_name="update",
         ),
         join_type="left",
     )


Test patch: