Repository: pandas-dev/pandas
Pull request: Regression tests to cover reset_index issue
- [x] closes #38147
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.


Problem statement:
BUG: reset_index() Fails on a Series/DataFrame Object that has "False" (bool type) as the Index Name
- [x] I have checked that this issue has not already been reported.

- [x] I have confirmed this bug exists on the latest version of pandas.

- [] (optional) I have confirmed this bug exists on the master branch of pandas.

-----

#### Code Sample, a copy-pastable example

```python
import pandas as pd

# Works
df1 = pd.Series(data=range(5, 10), index=range(0, 5))
df1.index.name = 'False'
df1.reset_index()

# Fails
df2 = pd.Series(data=range(5, 10), index=range(0, 5))
df2.index.name = False
df2.reset_index()

# Works
df1 = pd.DataFrame(data=range(5, 10), index=range(0, 5))
df1.index.name = 'False'
df1.reset_index()

# Fails
df2 = pd.DataFrame(data=range(5, 10), index=range(0, 5))
df2.index.name = False
df2.reset_index()
```

Stacktrace:
<details>
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-55bb91831e54> in <module>
      9 df2 = pd.Series(data=range(5, 10), index=range(0, 5))
     10 df2.index.name = False
---> 11 df2.reset_index()

~\Miniconda3\envs\vectorbt\lib\site-packages\pandas\core\series.py in reset_index(self, level, drop, name, inplace)
   1340         else:
   1341             df = self.to_frame(name)
-> 1342             return df.reset_index(level=level, drop=drop)
   1343 
   1344     # ----------------------------------------------------------------------

~\Miniconda3\envs\vectorbt\lib\site-packages\pandas\core\frame.py in reset_index(self, level, drop, inplace, col_level, col_fill)
   4602                 # to ndarray and maybe infer different dtype
   4603                 level_values = _maybe_casted_values(lev, lab)
-> 4604                 new_obj.insert(0, name, level_values)
   4605 
   4606         new_obj.index = new_index

~\Miniconda3\envs\vectorbt\lib\site-packages\pandas\core\frame.py in insert(self, loc, column, value, allow_duplicates)
   3494         self._ensure_valid_index(value)
   3495         value = self._sanitize_column(column, value, broadcast=False)
-> 3496         self._data.insert(loc, column, value, allow_duplicates=allow_duplicates)
   3497 
   3498     def assign(self, **kwargs) -> "DataFrame":

~\Miniconda3\envs\vectorbt\lib\site-packages\pandas\core\internals\managers.py in insert(self, loc, item, value, allow_duplicates)
   1171         if not allow_duplicates and item in self.items:
   1172             # Should this be a different kind of error??
-> 1173             raise ValueError(f"cannot insert {item}, already exists")
   1174 
   1175         if not isinstance(loc, int):

ValueError: cannot insert False, already exists
</details>

#### Problem description

Pandas index names support multiple object types as opposed to just `str`. I presume that the intention was that an index name is never anything other than a string, but I can only speculate. Interestingly enough, I did not encounter this issue on a DataFrame. This leads me to believe that the issue has to do with

I originally encountered this bug when loading data from a csv that had a header of `False`. Perhaps a clean enough work-around is to convert headers to strings when loading from any file type?

#### Expected Output

The index reset without the ValueError. It should match `df1`'s output.

#### Output of ``pd.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit           : None
python           : 3.8.5.final.0
python-bits      : 64
OS               : Windows
OS-release       : 10
machine          : AMD64
processor        : Intel64 Family 6 Model 142 Stepping 10, GenuineIntel
byteorder        : little
LC_ALL           : None
LANG             : None
LOCALE           : English_United States.1252

pandas           : 1.0.5
numpy            : 1.19.1
pytz             : 2020.1
dateutil         : 2.8.1
pip              : 20.1.1
setuptools       : 49.2.0.post20200712
Cython           : None
pytest           : None
hypothesis       : None
sphinx           : None
blosc            : None
feather          : None
xlsxwriter       : None
lxml.etree       : None
html5lib         : None
pymysql          : None
psycopg2         : None
jinja2           : 2.11.2
IPython          : 7.16.1
pandas_datareader: None
bs4              : None
bottleneck       : None
fastparquet      : None
gcsfs            : None
lxml.etree       : None
matplotlib       : 3.3.0
numexpr          : None
odfpy            : None
openpyxl         : None
pandas_gbq       : None
pyarrow          : None
pytables         : None
pytest           : None
pyxlsb           : None
s3fs             : None
scipy            : 1.5.2
sqlalchemy       : None
tables           : None
tabulate         : None
xarray           : None
xlrd             : None
xlwt             : None
xlsxwriter       : None
numba            : 0.50.1
</details>

Hints from issue discussion:
Hi,

thanks for your report. The problem lies in insert. Your DataFrame has a column 0. Unfortunately ``False == 0`` evaluates to ``True``. I do not know if this is trivial to fix.
This works now, may need tests

Commit message: add regression test to cover an issue #38147

Patch to review:
diff --git a/pandas/tests/frame/methods/test_reset_index.py b/pandas/tests/frame/methods/test_reset_index.py
index 8a11a59cdcb58..cbc11ef7f2c5f 100644
--- a/pandas/tests/frame/methods/test_reset_index.py
+++ b/pandas/tests/frame/methods/test_reset_index.py
@@ -773,3 +773,14 @@ def test_errorreset_index_rename(float_frame):
 
     with pytest.raises(IndexError, match="list index out of range"):
         stacked_df.reset_index(names=["new_first"])
+
+
+def test_reset_index_false_index_name():
+    # GH 38147
+    df1 = Series(data=range(5, 10), index=range(0, 5))
+    df1.index.name = False
+    df1.reset_index()
+
+    df2 = DataFrame(data=range(5, 10), index=range(0, 5))
+    df2.index.name = False
+    df2.reset_index()


Code review comments:
diff_hunk: @@ -773,3 +773,14 @@ def test_errorreset_index_rename(float_frame):
 
     with pytest.raises(IndexError, match="list index out of range"):
         stacked_df.reset_index(names=["new_first"])
+
+
+def test_reset_index_false_index_name():
+    # GH 38147
+    df1 = Series(data=range(5, 10), index=range(0, 5))
+    df1.index.name = False
+    df1.reset_index()
path: pandas/tests/frame/methods/test_reset_index.py
text: @user1:
Could you check the result? Like:
```
expected = DataFrame({False: range(0, 5), 0: range(5, 10)})
tm.assert_frame_equals(result, expected)
```

@author:
Sure!