Skip to content

fix: model-check direction mapping, partial-check reporting, mypy ratchet on main - #12

Merged
ogunc merged 4 commits into
mainfrom
fix/main-model-check-ci
Oct 15, 2026
Merged

ogunc merged 4 commits into
mainfrom
fix/main-model-check-ci

Conversation

@ogunc

@ogunc ogunc commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Summary

Four narrow follow-ups to the model check merged in #3; the last one turns the Type check (ratchet) step on main green again (235 errors against a budget of 234).

Linked issue

Follow-up to #3 (no separate issue).

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / tooling

Changes

  • core/model_check.py: zeroLength -dir values are mapped the way OpenSees does (1-3 translations, 4-6 rotations; in 2D direction 6 is the rotation about z and direction 3 is still accepted). A 2D rotational spring with -dir 6 was rejected by the check although the solver accepts it.
  • core/model_check.py, views/dialogs/model_check.py, views/main_window.py: a stability check skipped over the DOF limit is reported as incomplete, not as passed.
  • tools/typecheck.py, .github/workflows/ci.yml: the ratchet fails when mypy did not run (missing module, crash) instead of counting zero errors; mypy is pinned in the test job that runs it, the lint job installs only ruff.
  • views/main_window.py: the F6 Check Model action is built with setShortcut, which removes the one new mypy error. The budget stays at 234.

Architectural checklist

  • No from PySide6 in core/ or services/
  • No import openseespy in core/ or views/
  • Public functions have type hints + docstrings
  • Heavy work runs off the GUI thread (unchanged by this PR)

Testing

Linux, Python 3.12, OpenSeesPy 3.8.0, on this branch:

  • tests/unit plus tests/integration/test_model_check_zero_length.py: exit 0
  • tests/gui/test_model_check_gui.py: 12 passed (offscreen)
  • ruff check / ruff format --check: clean (ruff 0.16.8)
  • python tools/typecheck.py: 234 errors, budget 234 (on origin/main the same command reports 235)

New tests: tests/integration/test_model_check_zero_length.py (check and solver agree on 2D/3D rotational springs), tests/unit/test_typecheck_tool.py, additions to tests/unit/test_model_check.py and tests/gui/test_model_check_gui.py.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BMKaowUSuNdouA8qyopXxK


Generated by Claude Code

zeroLength -dir values are material directions, not nodal DOF numbers:
1-3 translate along and 4-6 rotate about the local x, y, z axes, and
OpenSees projects them onto the nodal DOF per dimension
(ZeroLength::setTran1d); in 2D it also reads direction 3 as 6. The check
used d - 1 and rejected d > ndf, so a 2D rotational spring written as
-dir 6 (the form the OpenSeesPy docs give) was reported as a DOF
mismatch and a mechanism, although OpenSees solves it.

zero_length_dof() holds the mapping per (ndm, ndf); a direction with no
stiffness in the model is the dof_mismatch, and the stability rows use
the mapped DOF. The unit test that expected -dir 6 to fail in 2D now
uses -dir 4, which has no stiffness there. New tests cover 2D and 3D
springs, the mapping table, and an integration test that runs the check
and the solver on the same model (rotation = M / k).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMKaowUSuNdouA8qyopXxK
When the stability test skipped a part over the DOF limit, the only trace
was an INFO finding: the summary still read "Model check passed ... no
problems found", the dialog showed it at info level, and the Run path
logged warnings only, so the skip never reached the console.

The report now counts skipped parts (stability_skipped_parts) and has
is_complete. An incomplete check without findings says "Model check
incomplete: ...; stability was not checked for N parts of the model",
a summary with findings gains an "Incomplete:" sentence, the dialog uses
the warning level, and Run logs the skipped-part notes and the summary.
A complete clean check still says "passed".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMKaowUSuNdouA8qyopXxK
…runs

tools/typecheck.py counted ": error:" lines and ignored the exit code, so
a missing mypy ("No module named mypy", exit 1) or a mypy crash (exit 2)
printed "0 error(s)" and passed. It now returns 2 unless mypy exited 0,
or exited 1 with at least one error line.

mypy==2.4.0 was pinned in the lint job, which never runs mypy, while the
test job that runs the ratchet installed whatever the dev extra resolves
(mypy>=1.8). The pin moves to the type-check step; lint installs ruff
only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMKaowUSuNdouA8qyopXxK
The new QAction("Check &Model…", self, shortcut="F6") call has no
matching overload in the PySide6 stubs; it added one call-overload error
to main_window.py, so the mypy ratchet read 235 against a budget of 234
and the CI type-check step would fail. Setting the shortcut after
construction keeps the budget where it is instead of raising it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMKaowUSuNdouA8qyopXxK
@ogunc
ogunc merged commit e802c7a into main Oct 15, 2026
8 of 9 checks passed
@ogunc
ogunc deleted the fix/main-model-check-ci branch October 20, 2026 09:22
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.

2 participants