REF: continue moving freq management off DatetimeArray/TimedeltaArray (GH#24566)#65285
Merged
mroeschke merged 5 commits intopandas-dev:mainfrom Apr 20, 2026
Merged
Conversation
_simple_new no longer accepts freq; callers that need to set freq do so explicitly via result._freq = freq. This makes _simple_new a pure values+dtype constructor.
Remove _maybe_clear_freq and the __setitem__ call site that invoked it. Freq management is now fully the Index's responsibility; setitem on a standalone array no longer mutates self._freq. __iadd__/__isub__ sync _freq from the arithmetic result (which at the array level is freq-agnostic), and DatetimeIndex.snap clears _freq on the result DTA to preserve its documented behavior.
The freq.setter on TimelikeOps is removed; freq mutation flows through DatetimeIndex/TimedeltaIndex.freq, which now performs the to_offset coercion and _validate_frequency check itself before assigning to arr._freq. The array's freq property is now read-only. PeriodArray (no _validate_frequency) raises a clear AttributeError if a caller tries to set freq through the Index, matching prior behaviour. __iadd__/__isub__ guard the _freq sync on dtype.kind to avoid touching PeriodArray, which derives freq from dtype rather than storing it.
…566) In-place arithmetic on a DTA/TDA used to sync `_freq` from the arithmetic result. That belonged to the array's freq-management era; under the current design `_freq` is Index-managed dumb storage on the array. Mutating values via __iadd__/__isub__ leaves _freq alone (it can go stale), matching __setitem__'s behaviour after pandas-dev#65276's cleanup. Tests that compared `dta += x` vs `dta + x` for the pd.array boxed case now sync the expected freq from the iadd-result before comparison, since the rebound `dta + x` returns a freq-stripped array while the in-place version preserves the array's pre-iadd freq.
- Replace the writable `freq: BaseOffset | None` class annotation on DatetimeLikeArrayMixin with an abstract read-only property so the TimelikeOps and PeriodArray overrides (both read-only) type-check. - Declare `_freq: BaseOffset | None` on TimelikeOps so reads of `self._freq` in `freq.getter` and `copy` resolve. - Use isinstance narrowing in DatetimeIndexOpsMixin.freq.setter so `arr._freq = value` type-checks (PeriodArray is excluded by the AttributeError branch). - Drop the now-unused `# type: ignore[override]` on PeriodArray.freq.
mroeschke
approved these changes
Apr 20, 2026
Member
|
Thanks @jbrockmendel |
4 tasks
Sharl0tteIsTaken
added a commit
to Sharl0tteIsTaken/pandas
that referenced
this pull request
Apr 22, 2026
…h-origin * upstream/main: (31 commits) DOC:Missing r in your (pandas-dev#65323) DOC: fix grammar in the .dt accessor section (pandas-dev#65325) REGR: restore rank() for ExtensionArrays with custom values for sorting (pandas-dev#64976) BUG: MultiIndex.get_loc returns scalar for unique key in non-unique index (pandas-dev#65234) BUG/TST: add test for _cast_pointwise_result robustness + fix some cases (pandas-dev#65318) BUG: fix .loc with tuple key on MultiIndex with IntervalIndex level (pandas-dev#65239) BUG: permit building from source with mingw (pandas-dev#64849) BUG: DataFrame.loc setitem with list-like value on single-column EA DataFrame (pandas-dev#65241) PERF: preserve block memory layout in Block.copy (GH#60469) (pandas-dev#65302) PERF: short-circuit sort_index(level=...) on monotonic non-MultiIndex (pandas-dev#65279) BUG: fix FloatingArray.astype(str) crash with distinguish_nan_and_na=True (pandas-dev#65038) BUG: fix to_timedelta ignoring unit for mixed round/non-round floats (pandas-dev#65170) BUG: DataFrame.loc preserves original index name when key is an Index (pandas-dev#65229) REF: continue moving freq management off DatetimeArray/TimedeltaArray (GH#24566) (pandas-dev#65285) REF: remove redundant BaseMaskedArray.map override (pandas-dev#65297) Bump github/codeql-action from 4.35.1 to 4.35.2 (pandas-dev#65310) Bump actions/setup-node from 6.3.0 to 6.4.0 (pandas-dev#65309) BUG: Fix formatters applied to wrong columns in truncated DataFrame.to_string (GH#35410) (pandas-dev#65288) PERF: optimize block consolidation (pandas-dev#64574) CLN: Replace no_default signature with False for allow_duplicates in insert and reset_index (pandas-dev#65146) ...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four small steps continuing GH#24566 (push freq handling from DTA/TDA to the Index level):
freqparam fromDTA/TDA._simple_new—_simple_newis now a pure values+dtype constructor; the four call sites that need to set freq do so explicitly viaresult._freq = freqafter construction.__setitem__no longer clears freq —_maybe_clear_freqand the__setitem__call site are removed._freqon the array is dumb storage that the Index manages, and is allowed to go stale after a mutation.DatetimeIndex.snapnow clears_freqon its result DTA explicitly.freqsetter fromTimelikeOps; move validation to the Index —DatetimeIndexOpsMixin.freq.setternow does theto_offsetcoercion,_validate_frequency, Tick/Day check, and ndim check before assigningarr._freq. PeriodArray (no_validate_frequency) raises a clear AttributeError when callers try to set freq through the Index.__iadd__/__isub__— they're now justself[:] = result[:]. Array's_freqstays as it was; the Index path naturally produces freq-correct results via__add__/__sub__. A few arithmetic tests had to align the expected freq for thepd.arrayboxed case, since the rebounddta + xreturns a freq-stripped array while in-placedta += xpreserves the array's pre-iadd freq.Test plan
pandas/tests/arrays/,pandas/tests/indexes/datetimes|timedeltas|period/,pandas/tests/arithmetic/all greenpandas/tests/series/,pandas/tests/frame/,pandas/tests/indexing/,pandas/tests/base/,pandas/tests/resample/,pandas/tests/reshape/,pandas/tests/tslibs/,pandas/tests/tseries/all green