Support resetting index with tuple name
State: closed

 - [x] closes #16164
 - [x] tests added / passed
 - [x] passes ``git diff master --name-only -- '*.py' | flake8 --diff``
 - [x] whatsnew entry

Notice the first commit is pure refactoring, and the bug is actually fixed by the [one-liner](https://github.com/pandas-dev/pandas/pull/16165/commits/e12bca109658435a709dda0858869323a7af6783#diff-1e79abbbdd150d4771b91ea60a4e1cc7R3036) second commit.

Labels:
name: Bug
name: MultiIndex

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=h1) Report
> Merging [#16165](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/075eca1fa085359b71f26d02c2f44156068e123c?src=pr&el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/16165/graphs/tree.svg?token=eZ4WkYLtcO&src=pr&height=150&width=650)](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #16165      +/-   ##
==========================================
+ Coverage   90.87%   90.88%   +0.01%     
==========================================
  Files         162      162              
  Lines       50816    50806      -10     
==========================================
- Hits        46178    46174       -4     
+ Misses       4638     4632       -6
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.66% <100%> (ø)` | :arrow_up: |
| #single | `40.33% <68.42%> (ø)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.58% <100%> (-0.02%)` | :arrow_down: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `91.63% <0%> (+0.32%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=footer). Last update [075eca1...e12bca1](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=h1) Report
> Merging [#16165](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/b6f65eb98f3d29d9ed61109d1a83f8fb72954c60?src=pr&el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/16165/graphs/tree.svg?width=650&src=pr&token=eZ4WkYLtcO&height=150)](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #16165      +/-   ##
==========================================
+ Coverage   90.85%   90.86%   +0.01%     
==========================================
  Files         162      162              
  Lines       50826    50819       -7     
==========================================
- Hits        46177    46176       -1     
+ Misses       4649     4643       -6
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.64% <100%> (+0.01%)` | :arrow_up: |
| #single | `40.33% <63.63%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.58% <100%> (-0.01%)` | :arrow_down: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `91.63% <0%> (+0.32%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=footer). Last update [b6f65eb...9e1bdba](https://codecov.io/gh/pandas-dev/pandas/pull/16165?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

this looks good. can you add a test which where you have another level already (and check the resetting), e.g.

```
In [3]: df = pd.DataFrame([[1, 2]], columns=pd.MultiIndex.from_product([['A'], ['a', 'b']]))
   ...: 
   ...: reind = df.set_index([('A', 'a')], append=True)
```

it works, just want to cover the bases. otherwise lgtm.
Can you check some more pathological cases? 
Eg when the length of the tuple does not match the number of levels? Not sure what the result should be of that (informative error or insert the tuple in first level), though. But good to at least assert its behaviour.
> Not sure what the result should be of that (informative error or insert the tuple in first level), though.

The current error is a quite informative "``*** ValueError: Item must have length equal to number of levels.``", and I think inserting tuple in first level would break the principle of least surprise.

However, it probably makes sense to use ``fill_value`` to fill keys which are shorter than the number of levels, rather than raising, so I added code making this happen.
thanks!
@toobaz Probably a not so important corner case, but could you also check how this interacts with the `col_level` argument?