One dt accessor where pandas has two, and the error a caller sees for it
- Dominant language
- Mojo
- Stars
- 1
- Forks
- 0
- Avg merge
- 1h 31m
- Merged PRs (30d)
- 640
Description
#345 puts `days` and `total_seconds`, which belong to a duration column, on the same accessor class as the calendar and clock names, which belong to a timestamp column. pandas splits `DatetimeProperties` from `TimedeltaProperties` and puts a different set of names on each.
## Why it is one class today
The core has one `Series.dt(name)` door for both, and the column's own logical type is what decides whether a name means anything. Splitting in the Python layer would mean reading the dtype on every `.dt` just to pick which object to hand back, which is a boundary call on an attribute access that otherwise makes none.
The visible difference is which error a caller sees. Asking a timestamp column for `days` is a dtype error here and an `AttributeError` in pandas. Asking a duration column for `year` is the same. The message is accurate in both cases and names the column type it got, so nobody is misled, but the exception type is wrong and a program that catches `AttributeError` around a feature probe will not catch it.
## What it is worth on the board
Nothing measurable today. The resolution cases build the namespace on a timestamp column, and every name that resolves on it also resolves in pandas, so the extra names are invisible to L0. They would become visible if the board ever built a `TimedeltaProperties` namespace and asked whether `year` is absent from it, which is a case worth adding to firepanda-compat independently of whether this is fixed.
## The options, so this is decided once
One. Leave it, and document the divergence in the compat registry rather than in a changelog paragraph, which is where a difference that is allowed to exist belongs.
Two. Split the class and read the dtype on every `.dt`. Correct, and it puts a boundary call on an attribute access.
Three. Split the class and keep the accessor a descriptor that reads the dtype once when it is built, which is exactly when pandas reads it. `s.dt` already builds an object per lookup and already crosses the boundary for anything it is asked, so the extra cost is one call at the moment the accessor is created rather than one per name. This looks like the right answer and it is not obviously so, because it makes `s.dt` itself able to raise, where today only the name after it can.
Option three is what pandas does. It is worth checking whether making `s.dt` raise on a non temporal column is desirable before choosing it, since that is a behaviour change on top of a structural one.
Contributor guide
Research direction
Start at the Series.dt(name) entry point and inspect how the resolution cases build the timestamp namespace. Compare that behavior with pandas' separate DatetimeProperties and TimedeltaProperties, then decide the dtype boundary behavior and add the duration-column case to firepanda-compat if that scope is chosen.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- pandas
- Domain
- api, data
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100