Skip to content

fix(v1): NaN scalars of any float dtype, non-unique merge dims, dead-code cleanup#854

Merged
FBumann merged 1 commit into
feat/arithmetic-conventionfrom
fix/v1-nan-scalar-cleanup
Jul 20, 2026
Merged

fix(v1): NaN scalars of any float dtype, non-unique merge dims, dead-code cleanup#854
FBumann merged 1 commit into
feat/arithmetic-conventionfrom
fix/v1-nan-scalar-cleanup

Conversation

@FBumann

@FBumann FBumann commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Follow-ups from reviewing #717.

Note

The following was generated by AI (Claude Opus 4.8), from a review of #717.

Three fixes, targeting the feat/arithmetic-convention branch:

1. §5 user-NaN check missed non-float64 numpy scalars. The scalar fast paths in _add_constant_* / _apply_constant_op_* guarded with isinstance(other, float). np.float64 subclasses Python float, but np.float32 / np.float16 do not — so a np.float32('nan') scalar slipped past the check and was silently added/multiplied into the expression instead of raising (v1) / warning (legacy). Added semantics.is_nan_scalar (float | np.floating) and applied it at all four sites.

2. conform_merge_dims crashed on a non-unique shared dim. The reorder-vs-mismatch detection called Index.get_indexer(ref), which raises InvalidIndexError on a non-unique index. This is a regression vs. master, where duplicate labels aligned positionally and succeeded. Guarded on idx.is_unique, so a non-unique differing index is reported as a §8 mismatch — legacy aligns positionally + warns (no crash), v1 raises the canonical Coordinate mismatch ValueError instead of the opaque one.

3. Dead-code / stale-doc cleanup. Removed the unused LEGACY_SEMANTICS_MESSAGE constant (config.py) and the obsolete EvolvingAPIWarning filter cells in the two piecewise example notebooks — those cells set semantics="v1" yet still filtered a warning that was renamed to LinopySemanticsWarning and no longer fires there.

Tests: added regression coverage for the NaN-scalar dtypes (float64/float32/float16 × add/sub/mul/div) and the duplicate-label merge on both conventions.

Full suite passes under both semantics (7856 passed, 626 skipped); ruff and pre-commit clean.

…rop dead code

Three follow-ups from the #717 review:

- §5 user-NaN check on the scalar fast path used `isinstance(other, float)`,
  which misses `np.float32`/`np.float16` NaN scalars (they don't subclass
  Python `float`). Such a scalar was silently added/multiplied into the
  expression instead of raising (v1) / warning (legacy). Add
  `semantics.is_nan_scalar` (float | np.floating) and use it at all four
  scalar sites.

- `conform_merge_dims` called `Index.get_indexer` on a shared dim with
  non-unique labels, raising an opaque `InvalidIndexError` — a regression
  vs. master, which aligned duplicate labels positionally. Guard on
  `idx.is_unique` so a non-unique differing index is reported as a §8
  mismatch: legacy aligns positionally + warns, v1 raises the canonical
  "Coordinate mismatch" ValueError.

- Remove the unused `LEGACY_SEMANTICS_MESSAGE` constant and the stale
  `EvolvingAPIWarning` filter cells in the piecewise notebooks (obsolete
  under `semantics="v1"`; the warning was renamed to LinopySemanticsWarning).

Adds regression tests for the NaN-scalar dtypes and the duplicate-label
merge on both conventions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@FBumann
FBumann force-pushed the fix/v1-nan-scalar-cleanup branch from b29d84b to b8d985e Compare July 20, 2026 08:33
@FBumann
FBumann merged commit b4ff193 into feat/arithmetic-convention Jul 20, 2026
1 of 2 checks passed
@FBumann
FBumann deleted the fix/v1-nan-scalar-cleanup branch July 20, 2026 08:40
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