Skip to content

fix(interop): reset dual mode to galgebra default in interop.Cl#556

Merged
utensil merged 2 commits intopygae:masterfrom
utiberious:fix/issue-555-interop-dual-mode-short-term
Apr 1, 2026
Merged

fix(interop): reset dual mode to galgebra default in interop.Cl#556
utensil merged 2 commits intopygae:masterfrom
utiberious:fix/issue-555-interop-dual-mode-short-term

Conversation

@utiberious
Copy link
Copy Markdown
Contributor

@utiberious utiberious commented Mar 31, 2026

Problem

galgebra.interop.kingdon.Cl sets Ga.dual_mode('Iinv+') globally. If galgebra.interop.Cl is called afterward in the same session, it silently inherits 'Iinv+' even though its documented promise is galgebra defaults ('I+'). See #555.

from galgebra.interop.kingdon import Cl as KCl
from galgebra.interop import Cl

ga_k, *_ = KCl(3)   # sets Iinv+ globally
ga_g, *_ = Cl(3)    # silently still Iinv+ -- wrong

Fix

galgebra.interop.Cl now calls Ga.dual_mode('I+') before building the algebra, mirroring the symmetric reset that kingdon.Cl does for 'Iinv+'. Sequential calls to both variants in one session are now safe without manual save/restore.

Updated kingdon.Cl docstring: the .. warning:: save/restore block becomes a .. note:: explaining that interop.Cl resets the mode, with explicit warning that algebras built under Iinv+ will compute duals with I+ once a subsequent galgebra.interop.Cl call is made.

Added test_Cl_dual_mode_reset to prevent regression.

Long-term

Per-instance dual_mode_value on Ga is tracked on feat/issue-555-interop-dual-mode-per-instance (see #555). That removes the global mutation entirely.

See #555.

Copy link
Copy Markdown
Member

@utensil utensil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix.

The one-line reset is correct and mirrors what kingdon.Cl already does for Iinv+. Two requests before merge:

  1. No test for the actual bug. The existing tests never call KCl first, so they would pass without the fix. Please add:
from galgebra.interop.kingdon import Cl as KCl
from galgebra.interop import Cl
from galgebra.ga import Ga

KCl(3)
Cl(3)
assert Ga.dual_mode_value == 'I+'
  1. PR body says "Fixes #555 (short-term)" which auto-closes 555 on merge. Change to "see #555" so the tracking issue stays open for the long-term per-instance fix.

One docstring nit: the note in kingdon.py says mixing is safe "as long as each call is followed by the code that uses that algebra before the next Cl call". Could be clearer that algebras built under Iinv+ will compute duals with I+ after a subsequent Cl() call.

galgebra.interop.Cl now calls Ga.dual_mode('I+') before building the
algebra, mirroring what kingdon.Cl does for 'Iinv+'. This prevents
silent session contamination when both Cl variants are used in the same
session (pygae#555).

Update kingdon.Cl docstring: the save/restore warning becomes a note
explaining that interop.Cl resets the mode, so sequential calls are safe
without manual save/restore.

Fixes pygae#555 (short-term). Long-term per-instance fix tracked on
feat/issue-555-interop-dual-mode-per-instance.
Add test_Cl_dual_mode_reset: calls kingdon.Cl (sets Iinv+) then
galgebra.interop.Cl and asserts dual mode is reset to I+. Without the
fix in _cl.py this test fails.

Clarify kingdon.Cl note: explicitly warn that algebras built under Iinv+
will compute duals with I+ once a subsequent galgebra.interop.Cl call is
made.
@utiberious utiberious force-pushed the fix/issue-555-interop-dual-mode-short-term branch from fd3f4f7 to 9a682a7 Compare March 31, 2026 11:39
@utensil utensil added this to the 0.6.0 milestone Mar 31, 2026
@utensil utensil added bug component: core Ga, Mv, Metric, etc labels Mar 31, 2026
@utensil utensil merged commit 1a87e38 into pygae:master Apr 1, 2026
6 checks passed
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 1, 2026
Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (pygae#550, closes pygae#524), Mv.__rtruediv__
(pygae#543, closes pygae#512), shirokov_inverse/hitzer_inverse (pygae#530).

Bugs: interop dual mode contamination (pygae#556, closes pygae#555), norm() Abs
wrapping (pygae#554, closes pygae#522), is_versor() improvement (pygae#536, closes pygae#533).

Examples/docs: sundial + cheatsheet tests (pygae#549+pygae#557, closes pygae#506),
coords tutorial (pygae#551), README ops (pygae#548, closes pygae#523).

Tests/maintenance: lt.matrix() regression tests (pygae#558, closes pygae#461),
extra-cdot regression test (pygae#545), er_blade + ReciprocalFrame refactors
(pygae#552+pygae#553), CI fix (pygae#535).
utensil pushed a commit that referenced this pull request Apr 1, 2026
* docs: add 0.6.0 changelog entries

Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (#550, closes #524), Mv.__rtruediv__
(#543, closes #512), shirokov_inverse/hitzer_inverse (#530).

Bugs: interop dual mode contamination (#556, closes #555), norm() Abs
wrapping (#554, closes #522), is_versor() improvement (#536, closes #533).

Examples/docs: sundial + cheatsheet tests (#549+#557, closes #506),
coords tutorial (#551), README ops (#548, closes #523).

Tests/maintenance: lt.matrix() regression tests (#558, closes #461),
extra-cdot regression test (#545), er_blade + ReciprocalFrame refactors
(#552+#553), CI fix (#535).

* docs: add missing issue link for #551 entry

* docs: add changelog entry for #560 (Lt callable zero fix)

* docs: move Lt zero fix into bug group, use issue #540 as reference
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
…e#556)

* fix(interop): reset dual mode to galgebra default in interop.Cl

galgebra.interop.Cl now calls Ga.dual_mode('I+') before building the
algebra, mirroring what kingdon.Cl does for 'Iinv+'. This prevents
silent session contamination when both Cl variants are used in the same
session (pygae#555).

Update kingdon.Cl docstring: the save/restore warning becomes a note
explaining that interop.Cl resets the mode, so sequential calls are safe
without manual save/restore.

Fixes pygae#555 (short-term). Long-term per-instance fix tracked on
feat/issue-555-interop-dual-mode-per-instance.

* test(interop): add regression test for dual mode reset in interop.Cl

Add test_Cl_dual_mode_reset: calls kingdon.Cl (sets Iinv+) then
galgebra.interop.Cl and asserts dual mode is reset to I+. Without the
fix in _cl.py this test fails.

Clarify kingdon.Cl note: explicitly warn that algebras built under Iinv+
will compute duals with I+ once a subsequent galgebra.interop.Cl call is
made.
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
* docs: add 0.6.0 changelog entries

Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (pygae#550, closes pygae#524), Mv.__rtruediv__
(pygae#543, closes pygae#512), shirokov_inverse/hitzer_inverse (pygae#530).

Bugs: interop dual mode contamination (pygae#556, closes pygae#555), norm() Abs
wrapping (pygae#554, closes pygae#522), is_versor() improvement (pygae#536, closes pygae#533).

Examples/docs: sundial + cheatsheet tests (pygae#549+pygae#557, closes pygae#506),
coords tutorial (pygae#551), README ops (pygae#548, closes pygae#523).

Tests/maintenance: lt.matrix() regression tests (pygae#558, closes pygae#461),
extra-cdot regression test (pygae#545), er_blade + ReciprocalFrame refactors
(pygae#552+pygae#553), CI fix (pygae#535).

* docs: add missing issue link for pygae#551 entry

* docs: add changelog entry for pygae#560 (Lt callable zero fix)

* docs: move Lt zero fix into bug group, use issue pygae#540 as reference
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug component: core Ga, Mv, Metric, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants