Repository: modin-project/modin

Issue:
read_csv fails with squeeze=True parameter
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Linux Ubuntu 18.04
- **Modin version** (`modin.__version__`): 0.7.3+334.g03fe0d6
- **Python version**: 3.8.5
- **Code we can use to reproduce**:
```
import pandas
import modin.pandas as pd
import os

test_filename = "test.csv"
csv_single_col = """1
2
3
"""

try :
    with open(test_filename, "w") as f:
        f.write(csv_single_col)

    df_pandas = pandas.read_csv(test_filename, squeeze=True)
    repr(df_pandas)
    df_pd = pd.read_csv(test_filename, squeeze=True)
    repr(df_pd)
finally:
    os.remove(test_filename)
```

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
Calling Modin `read_csv` function with `squeeze=True` parameter causes infinite recursion error.
<!-- Describe the problem clearly here. -->

### 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. -->
```
Traceback (most recent call last):
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 2945, in __getattr__
    return object.__getattribute__(self, key)
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 209, in _get_columns
    return self._query_compiler.columns
  File "/localdisk/amyskov/miniconda3_2/envs/modin_test3/lib/python3.8/site-packages/pandas/core/generic.py", line 5270, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'columns'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 2945, in __getattr__
    return object.__getattribute__(self, key)
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 209, in _get_columns
    return self._query_compiler.columns
  File "/localdisk/amyskov/miniconda3_2/envs/modin_test3/lib/python3.8/site-packages/pandas/core/generic.py", line 5270, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'columns'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_squeeze.py", line 18, in <module>
    repr(df_pd)
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 171, in __repr__
    result = repr(self._build_repr_df(num_rows, num_cols))
  File "/localdisk/amyskov/modin/modin/pandas/base.py", line 62, in _build_repr_df
    hasattr(self, "columns") and len(self.columns) == 0
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 2947, in __getattr__
    if key in self.columns:
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 2947, in __getattr__
    if key in self.columns:
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 2947, in __getattr__
    if key in self.columns:
  [Previous line repeated 986 more times]
  File "/localdisk/amyskov/modin/modin/pandas/base.py", line 3399, in __getattribute__
    return object.__getattribute__(self, item)
  File "/localdisk/amyskov/modin/modin/pandas/dataframe.py", line 209, in _get_columns
    return self._query_compiler.columns
  File "/localdisk/amyskov/miniconda3_2/envs/modin_test3/lib/python3.8/site-packages/pandas/core/generic.py", line 5270, in __getattr__
    return object.__getattribute__(self, name)
RecursionError: maximum recursion depth exceeded while calling a Python object
```



Discussion:
This parameter should not be sent to the workers, we handle the conversion in the API layer.
@amyskov Can this be closed? I think we handle the `squeeze` parameter now.
Unfortunately issue is still persists in the current master, reproducer fails with traceback below:
```
Traceback (most recent call last):
  File "check.py", line 17, in <module>
    df_pd = pd.read_csv(test_filename, squeeze=True)
  File "/modin/modin/pandas/io.py", line 131, in read_csv
    return _read(**kwargs)
  File "/modin/modin/pandas/io.py", line 59, in _read
    pd_obj = FactoryDispatcher.read_csv(**kwargs)
  File "/modin/modin/data_management/factories/dispatcher.py", line 178, in read_csv
    return cls.__factory._read_csv(**kwargs)
  File "/modin/modin/data_management/factories/factories.py", line 206, in _read_csv
    return cls.io_cls.read_csv(**kwargs)
  File "/modin/modin/engines/base/io/file_dispatcher.py", line 68, in read
    query_compiler = cls._read(*args, **kwargs)
  File "/modin/modin/engines/base/io/text/csv_dispatcher.py", line 118, in _read
    column_names = pd_df_metadata.columns
  File "/miniconda3/envs/modin/lib/python3.8/site-packages/pandas/core/generic.py", line 5487, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'columns'
```

Resolving patch:
diff --git a/modin/core/io/text/csv_dispatcher.py b/modin/core/io/text/csv_dispatcher.py
--- a/modin/core/io/text/csv_dispatcher.py
+++ b/modin/core/io/text/csv_dispatcher.py
@@ -159,7 +159,6 @@ def _read(cls, filepath_or_buffer, **kwargs):
             column_names=column_names,
             skiprows_md=skiprows_md if should_handle_skiprows else None,
             header_size=header_size,
-            squeeze=kwargs.get("squeeze", False),
             skipfooter=kwargs.get("skipfooter", None),
             parse_dates=kwargs.get("parse_dates", False),
             nrows=kwargs.get("nrows", None) if should_handle_skiprows else None,
@@ -351,8 +350,6 @@ def _get_new_qc(
                 new_query_compiler = new_query_compiler.view(
                     pandas.RangeIndex(len(new_query_compiler.index))[:nrows]
                 )
-        if kwargs.get("squeeze", False) and len(new_query_compiler.columns) == 1:
-            return new_query_compiler[new_query_compiler.columns[0]]
         if index_col is None:
             new_query_compiler._modin_frame.synchronize_labels(axis=0)
 
diff --git a/modin/pandas/io.py b/modin/pandas/io.py
--- a/modin/pandas/io.py
+++ b/modin/pandas/io.py
@@ -56,6 +56,7 @@ def _read(**kwargs):
     from modin.core.execution.dispatching.factories.dispatcher import FactoryDispatcher
 
     Engine.subscribe(_update_engine)
+    squeeze = kwargs.pop("squeeze", False)
     pd_obj = FactoryDispatcher.read_csv(**kwargs)
     # This happens when `read_csv` returns a TextFileReader object for iterating through
     if isinstance(pd_obj, pandas.io.parsers.TextFileReader):
@@ -64,7 +65,10 @@ def _read(**kwargs):
             query_compiler=reader(*args, **kwargs)
         )
         return pd_obj
-    return DataFrame(query_compiler=pd_obj)
+    result = DataFrame(query_compiler=pd_obj)
+    if squeeze:
+        return result.squeeze(axis=1)
+    return result
 
 
 @_inherit_docstrings(pandas.read_csv)


Test patch:
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -362,18 +362,8 @@ def test_read_csv_skipinitialspace(self):
     @pytest.mark.parametrize(
         "test_case",
         [
-            pytest.param(
-                "single_element",
-                marks=pytest.mark.xfail(
-                    reason="infinite recursion error - issue #2032"
-                ),
-            ),
-            pytest.param(
-                "single_column",
-                marks=pytest.mark.xfail(
-                    reason="infinite recursion error - issue #2032"
-                ),
-            ),
+            "single_element",
+            "single_column",
             "multiple_columns",
         ],
     )