From 13dede32694c4c3a356fd622bd3e68ec0a428487 Mon Sep 17 00:00:00 2001 From: FBumann <117816358+FBumann@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:49:26 +0200 Subject: [PATCH] docs(v1): cover unlabeled-operand and grouper cases, fold MI-level into MI row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The migration guide's fix table covered the core absence + alignment + aux-coord + MultiIndex-dim + groupby-result cases, but three issue-backed v1 changes were under-covered. Add rows and mirror two into the release-notes v1 summary: - Unlabeled operand (numpy / list / polars) pairs to dims by size; ambiguous or no-size-match raises (#736) — the object-scope premise. - A reordered/mismatched groupby grouper raises rather than reindexing positionally (#827). - MultiIndex-level projection: v1 rejects the MultiIndex *dimension* at construction, so the per-level-input case is folded into the existing MultiIndex row — decompose with reset_index, then project by the level aux coord. (The convention.md §11 example still shows the legacy-shaped `.get_level_values` snippet, which cannot run under v1 — flagged for the spec pass.) Release notes already carry the level-projection deprecation separately, so only #736 and the grouper point are mirrored there. Co-Authored-By: Claude Opus 4.8 (1M context) --- doc/migrating-to-v1.rst | 22 +++++++++++++++++++--- doc/release_notes.rst | 2 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/doc/migrating-to-v1.rst b/doc/migrating-to-v1.rst index 3b5e9bdc2..8dfb3562e 100644 --- a/doc/migrating-to-v1.rst +++ b/doc/migrating-to-v1.rst @@ -99,6 +99,12 @@ Every row is a legacy guess that becomes an explicit rule under v1. The - Raises (``join="exact"`` — no silent reindex). - ``.sortby(dim)`` / ``.reindex`` one side to match, or a reindexing ``join=`` (``"outer"`` / ``"inner"`` / ``"left"`` / ``"right"``). + * - An **unlabeled** operand (numpy array, list, polars ``Series``) + - Pairs with the linopy operand's dimensions by *size*; an ambiguous + match (a square array, or two dimensions of equal length) or no size + match raises rather than guessing. + - Wrap it in a ``DataArray`` / ``Series`` / ``DataFrame`` with named + dimensions so it aligns by label. * - A **masked / absent** variable in arithmetic - Absence propagates (the slot stays absent) instead of counting as ``0``. - Decide the intent: ``.fillna(0)`` to keep the old "treat as zero", or @@ -107,14 +113,24 @@ Every row is a legacy guess that becomes an explicit rule under v1. The - Raises instead of silently dropping one. - ``.drop_vars(name)`` to remove the coord, or ``.assign_coords(name=...)`` to relabel one side. - * - A first-class ``pd.MultiIndex`` **dimension** - - Rejected; v1 uses a flat dimension with the levels as aux coords. - - ``.reset_index(dim)`` to flatten before building the model. + * - A first-class ``pd.MultiIndex`` **dimension** — and a per-*level* input + onto it (e.g. per-``period`` bounds onto a ``(period, timestep)`` + ``snapshot``) + - Rejected; v1 uses a flat dimension with the levels as aux coords, and a + per-level input must be mapped onto the flat dimension explicitly (no + implicit projection). Affects PyPSA multi-investment models. + - ``.reset_index(dim)`` to flatten, then project the per-level input by + its level aux coord. * - A multi-key ``groupby(...).sum()`` result - A flat ``group`` dimension with the keys as aux coords (not a stacked ``group`` MultiIndex). - Select on the key aux coords; convert an existing result with ``.reset_index("group")``. + * - A ``groupby`` grouper (``Series`` / ``DataArray`` / ``DataFrame`` / + coord name) with a differing label set or order + - Raises — the grouper aligns to the grouped dimension by label, never + by position. + - ``.sortby`` / ``.reindex`` the grouper to the dimension's labels. The full, normative rule list lives in the `arithmetic convention `_. diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 778096e73..f4030da02 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -12,10 +12,12 @@ Upcoming Version * A new, stricter convention for how linopy arithmetic aligns coordinates and treats missing data is available behind ``linopy.options["semantics"] = "v1"``. Legacy behaviour remains the **default** in this release; v1 is opt-in. In short, under v1: * shared dimensions align by label with ``join="exact"`` — a differing label set *or* a pure reorder (same labels, different order) raises instead of silently filling, dropping, or pairing by position. Resolve explicitly with ``.sel`` / ``.reindex`` / ``.assign_coords``, or pass an explicit ``join=`` to the named ``.add`` / ``.sub`` / ``.mul`` / ``.div`` / ``.le`` / ``.ge`` / ``.eq`` methods. + * an *unlabeled* operand (a numpy array, list, or polars ``Series``) pairs with the linopy operand's dimensions by size; an ambiguous match (a square array, or two equal-length dimensions) or no size match raises instead of guessing. Wrap it in a ``DataArray`` to name the dimensions. (https://github.com/PyPSA/linopy/issues/736) * a ``NaN`` in a user-supplied constant raises, rather than being silently filled (with a value that used to differ per operator). * *absence* — masked, reindexed, or shifted-in slots — is a first-class state that propagates through every operator, instead of collapsing to zero. * conflicting auxiliary coordinates raise, instead of being silently dropped. * a first-class ``pd.MultiIndex`` dimension is rejected in favour of a flat dimension with the levels as auxiliary coordinates. + * a ``groupby`` grouper aligns to the grouped dimension by label — a grouper whose labels differ in set or order from the dimension raises instead of being matched positionally, and a multi-key grouper yields a flat ``group`` dimension (keys as aux coords) rather than a stacked ``group`` MultiIndex. (https://github.com/PyPSA/linopy/issues/827) * Every operation whose result changes under v1 emits a ``LinopySemanticsWarning`` under legacy, naming the fix — so a model can be migrated incrementally before opting in. The full rules are specified in `the arithmetic convention `_.