df.columns, df.index and s.index cannot be assigned to
- Dominant language
- Mojo
- Stars
- 1
- Forks
- 0
- PR merge metrics
- PR metrics pending
Description
Renaming every column in one line is one of the most common things anybody does to a pandas frame, and it does not work here.
```python
df.columns = ["x", "y"]
# AttributeError: property 'columns' of 'DataFrame' object has no setter
s.index = [9, 8]
# AttributeError: property 'index' of 'Series' object has no setter
```
Measured against the pinned pandas 3.0.3, all three of `DataFrame.columns`, `DataFrame.index` and `Series.index` accept an assignment, and a wrong length is a `ValueError` reading `Length mismatch: Expected axis has 2 elements, new values have 1 elements`.
This surfaced from the conformance suite in an indirect way that is worth writing down, because the label it arrived under made it look like a harness quibble and it is not. Seven L0 records fail with `'property', expected 'attribute'`. The suite classifies a member by asking whether the class attribute is an instance of the builtin `property`, and pandas' `columns` and `index` are `pandas._libs.properties.AxisProperty`, a Cython descriptor that is not one, so pandas is recorded as `attribute` and firepanda as `property`. That looks like the suite testing a CPython implementation detail.
The reason it is not is that the two kinds differ in the one way a user can feel. `AxisProperty` has a setter and a bare read only `property` does not, so the difference the suite is reporting is exactly this gap, seen through a vocabulary that does not have a word for it. The right fix is here rather than in the harness.
Seven names are affected. `DataFrame.columns`, `DataFrame.index` and `Series.index` are the ones that should take an assignment. `Index.dtype`, `Index.is_unique`, `Index.hasnans` and `Index.inferred_type` are `CachedProperty` in pandas and are read only there too, so those four are the harness vocabulary and not a gap, and they are worth separating out before anybody starts on this.
### What the setter has to do
Length is checked against the existing axis and a mismatch raises `ValueError` with pandas' wording above. Assigning to `DataFrame.columns` renames in place without touching any column data. Assigning to `DataFrame.index` or `Series.index` replaces the labels without reordering anything, which is the difference between this and `reindex` and is worth a test of its own, since getting it wrong quietly reorders a user's rows.
Related to [#254](https://github.com/tamnd/firepanda/issues/254), which is that `df.columns` answers with a Python list where pandas answers with an `Index`. These are separate but they touch the same accessor, and doing them together would mean one pass over the type rather than two.
Contributor guide
Assessment
This issue has not been assessed yet.