Skip to content

fix(v1): warn on legacy multi-key groupby MultiIndex; suggest reset_index#840

Merged
FBumann merged 1 commit into
feat/arithmetic-conventionfrom
fix/v1-groupby-observed-mi-warn
Jul 16, 2026
Merged

fix(v1): warn on legacy multi-key groupby MultiIndex; suggest reset_index#840
FBumann merged 1 commit into
feat/arithmetic-conventionfrom
fix/v1-groupby-observed-mi-warn

Conversation

@FBumann

@FBumann FBumann commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Note

The following was generated by AI.

Found by working through open-items.md — the transition-surface completeness audit (Stage 1: every v1 behaviour-change must warn under legacy, the "no silent change" guarantee).

Audit

Probed every convention §'s legacy→v1 divergence under legacy and checked a LinopySemanticsWarning fires: §5 user-NaN (+/*), §6 masked variable through every operator + comparison, §8 set-mismatch / reorder (const, merge, coeff, rhs <=/>=/==), §11 aux-coord conflict, §12 RHS NaN, #803 MultiIndex construction, unlabeled ambiguous pairing, multi-key groupby. All warned except one.

The gap

groupby([names]).sum(observed=True) mints a stacked group MultiIndex under legacy (v1 returns a flat group dim + key aux coords) but emitted no warning — only the DataFrame-grouper spelling of the same operation warned:

grouper observed legacy warned?
groupby(df) any MultiIndex
groupby([names]) False flat (unstacked) — (no MI)
groupby([names]) True MultiIndex ❌ → now ✅

So a legacy model doing groupby(["country","carrier"]).sum(observed=True) and consuming .sel(group=(...)) would break under v1 with no deprecation notice — exactly the PyPSA-Eur CCL pattern.

Fix

_restore_multikey_index gated the warning on user_facing (DataFrame groupers only). The correct condition is "legacy keeps a surviving group MultiIndex" — stacked_survives and not is_v1(), which the code already reaches only under legacy. Dropped the user_facing parameter; reworded the message ("multi-key groupby", not "frame grouper").

The warning now hands the user a robust one-line migration. .reset_index("group") on the legacy MI result yields exactly the v1 flat group dim + aux coords — verified by assert_linequal(legacy_mi.reset_index("group"), v1_flat) built from the same expression. The message includes it as a Convert: line.

Tests: namelist+observed warn/flat, the reset_index → v1 migration equivalence, and scoped test_observed_silences_blowup_warning to the blowup warning specifically (it had used a blanket simplefilter("error")).

open-items.md records the audit and that no other silent fork site remains.

Full suite green; ruff/mypy clean.

…ndex

Transition-surface audit (working through open-items.md) found one silent
legacy->v1 divergence: `groupby([names]).sum(observed=True)` mints a stacked
`group` MultiIndex under legacy (v1 returns a flat dim + aux coords) but emitted
no warning — only DataFrame groupers did. A legacy model consuming
`.sel(group=(...))` would break under v1 with no deprecation notice.

- _restore_multikey_index: warn whenever legacy keeps a *surviving* group
  MultiIndex (drop the DataFrame-only `user_facing` gate); reword the message.
- The warning now offers a robust migration: `.reset_index('group')` yields
  exactly the v1 flat result (pinned by assert_linequal from the same expr).
- Tests: namelist+observed warn/flat, the reset_index->v1 equivalence; scope
  test_observed_silences_blowup_warning to the blowup warning.
- open-items.md records the audit; no other silent fork site found.

Full suite green (7840 passed); ruff/mypy clean (pre-existing solvers.py ignore
aside).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@FBumann FBumann merged commit c4bbc7e into feat/arithmetic-convention Jul 16, 2026
1 of 2 checks passed
@FBumann FBumann deleted the fix/v1-groupby-observed-mi-warn branch July 16, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant