Skip to content

Align moment magnitude overload defaults with the implementations - #105

Merged
lispandfound merged 2 commits into
mainfrom
fix/90-moment-overload-defaults
Sep 9, 2026
Merged

Align moment magnitude overload defaults with the implementations#105
lispandfound merged 2 commits into
mainfrom
fix/90-moment-overload-defaults

Conversation

@lispandfound

Copy link
Copy Markdown
Contributor

Fixes #90

Problem

The @typing.overload stubs put the default on the Literal[False] variant while both implementations default bold_m to True:

# before
@typing.overload
def moment_to_magnitude(moment: float, bold_m: typing.Literal[True]) -> BoldM: ...
@typing.overload
def moment_to_magnitude(moment: float, bold_m: typing.Literal[False] = False) -> Mw: ...
def moment_to_magnitude(moment: float, bold_m: bool = True) -> BoldM | Mw:

So a bare moment_to_magnitude(m) resolved to the Literal[False] overload and was typed Mw, while the value returned at runtime is a BoldM. magnitude_to_moment had the same mismatch.

Mw and BoldM are conventions this module deliberately keeps apart in the type system, and the difference is not notional:

moment_to_magnitude(1e19)        = 6.6334   <- actual (BoldM)
moment_to_magnitude(1e19, False) = 6.6000   <- what the stub claimed
                      difference = 0.0334 magnitude units, ~5% in moment

Verification with ty (the checker in the dev group)

reveal_type on the three call forms, plus a BoldM passed positionally:

expression before after
moment_to_magnitude(1e19) Mw BoldM
moment_to_magnitude(1e19, True) BoldM BoldM
moment_to_magnitude(1e19, False) Mw Mw
magnitude_to_moment(BoldM(6.6)) error: Expected Mw, found BoldM clean

Changes

Runtime behaviour is untouched — this is a stub-only change.

  • Move = True onto the Literal[True] overloads.
  • Drop the default from the Literal[False] overloads, so passing False stays explicit (a default on both variants would make a bare call ambiguous).

Verification

  • pytest tests/test_moment.py — 14 passed.
  • ruff check, ruff format, numpydoc lint clean.

🤖 Generated with Claude Code

lispandfound and others added 2 commits September 8, 2026 23:12
The overload stubs for moment_to_magnitude and magnitude_to_moment put
the default on the Literal[False] variant, while both implementations
default bold_m to True. A bare moment_to_magnitude(m) was therefore typed
Mw but computed a BoldM -- a real 0.033 magnitude unit (~5% moment)
discrepancy between the declared and actual convention.

Moves the default onto the Literal[True] overloads. Verified with ty:
moment_to_magnitude(1e19) now reveals BoldM rather than Mw, and
magnitude_to_moment(BoldM(6.6)) no longer reports
"Expected Mw, found BoldM".

Fixes #90

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Corrected overload defaults surfaced a genuine inconsistency in
test_moment.py: the call constructs an Mw(5.0) but omitted bold_m, so at
runtime bold_m defaulted to True and the BoldM formula was applied to an
Mw value. The test only asserts that a later KeyError is raised, so the
wrong magnitude went unnoticed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lispandfound

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up commit: the corrected overload defaults made ci / typecheck fail, and the failure was a real bug the stubs had been hiding.

tests/test_moment.py:202 constructs an Mw but omitted bold_m:

moment_newton_metre = moment.magnitude_to_moment(Mw(5.0))

The implementation defaults bold_m=True, so the BoldM formula was applied to an Mw value. Under the old stubs a bare call resolved to the Mw, Literal[False] overload, so the checker saw nothing wrong; with the defaults corrected it reports Expected BoldM, found Mw — exactly the mismatch that was there all along.

The test only asserts that a later KeyError is raised, so the wrong magnitude never affected the result and nothing caught it.

Fixed by passing the convention explicitly: magnitude_to_moment(Mw(5.0), bold_m=False).

ty check over the whole project now reports the same 13 diagnostics as main (all pre-existing; my local ty is newer than CI's, which is why main is green on CI). This is a small piece of evidence that the change does what it is supposed to: it makes the checker able to see convention mix-ups at call sites.

@lispandfound
lispandfound merged commit 8d3e140 into main Sep 9, 2026
7 checks passed
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.

moment.py: overload defaults for bold_m contradict the implementation defaults

1 participant