Skip to content

Commit 0ffcd88

Browse files
sbryngelsonclaude
andcommitted
Address PR review: --fix-only, CLAUDE.md update, hash tests
- Use ruff check --fix-only instead of --fix || true so genuine ruff failures propagate while still tolerating unfixable violations - Update CLAUDE.md: Pylint -> Ruff in lint command description - Add 4 unit tests for MFCConfig.__hash__ (hash/eq contract, set/dict usage) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ef22020 commit 0ffcd88

5 files changed

Lines changed: 44 additions & 6 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ All commands run from the repo root via `./mfc.sh`.
4141
# Verification (pre-commit CI checks)
4242
./mfc.sh precheck -j 8 # Run all 5 lint checks (same as CI gate)
4343
./mfc.sh format -j 8 # Auto-format Fortran (.fpp/.f90) + Python
44-
./mfc.sh lint # Pylint + Python unit tests
44+
./mfc.sh lint # Ruff lint + Python unit tests
4545
./mfc.sh spelling # Spell check
4646

4747
# Module loading (HPC clusters only — must use `source`)

docs/documentation/contributing.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -715,14 +715,15 @@ Every push to a PR triggers CI. Understanding the pipeline helps you fix failure
715715

716716
### Lint Gate (runs first, blocks all other jobs)
717717

718-
All four checks must pass before any builds start:
718+
All five checks must pass before any builds start:
719719

720720
1. **Formatting**`./mfc.sh format` (auto-handled by pre-commit hook)
721721
2. **Spelling**`./mfc.sh spelling`
722-
3. **Toolchain lint**`./mfc.sh lint` (Python code quality)
722+
3. **Toolchain lint**`./mfc.sh lint` (ruff + Python unit tests)
723723
4. **Source lint** — checks for:
724724
- Raw `!$acc` or `!$omp` directives (must use Fypp GPU macros)
725725
- Double-precision intrinsics (`dsqrt`, `dexp`, `dble`, etc.)
726+
5. **Doc references** — validates documentation cross-references
726727

727728
### Build and Test Matrix
728729

toolchain/bootstrap/format.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ if [[ ${#PATHS[@]} -gt 0 ]]; then
5454
fi
5555

5656
# Format Python files with ruff (auto-fix lint issues, then format)
57-
ruff check --fix $SEARCH_PATHS > /dev/null || true
57+
ruff check --fix-only $SEARCH_PATHS
5858
if ! ruff format $SEARCH_PATHS; then
5959
error "Formatting Python files failed."
6060
exit 1
@@ -70,7 +70,7 @@ else
7070
fi
7171

7272
# Format Python files with ruff (auto-fix lint issues, then format)
73-
ruff check --fix toolchain/ examples/ benchmarks/ > /dev/null || true
73+
ruff check --fix-only toolchain/ examples/ benchmarks/
7474
if ! ruff format toolchain/ examples/ benchmarks/; then
7575
error "Formatting Python files failed."
7676
exit 1

toolchain/bootstrap/lint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ done
1414

1515
log "(venv) Auto-fixing safe lint issues with$MAGENTA ruff$COLOR_RESET..."
1616

17-
ruff check --fix toolchain/ examples/*/case.py benchmarks/*/case.py > /dev/null || true
17+
ruff check --fix-only toolchain/ examples/*/case.py benchmarks/*/case.py
1818

1919
log "(venv) Running$MAGENTA ruff$COLOR_RESET on$MAGENTA MFC$COLOR_RESET's $MAGENTA""toolchain$COLOR_RESET."
2020

toolchain/mfc/cli/test_cli.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,42 @@ def test_docs_generates_markdown(self):
142142
self.assertIn("#", output) # Should contain markdown headers
143143

144144

145+
class TestMFCConfigHash(unittest.TestCase):
146+
"""Test MFCConfig __hash__ / __eq__ contract."""
147+
148+
def test_equal_configs_same_hash(self):
149+
"""Equal MFCConfig objects must have the same hash."""
150+
from ..state import MFCConfig
151+
152+
a = MFCConfig()
153+
b = MFCConfig()
154+
self.assertEqual(a, b)
155+
self.assertEqual(hash(a), hash(b))
156+
157+
def test_different_configs_different_hash(self):
158+
"""Different MFCConfig objects should (likely) have different hashes."""
159+
from ..state import MFCConfig
160+
161+
a = MFCConfig(debug=False)
162+
b = MFCConfig(debug=True)
163+
self.assertNotEqual(a, b)
164+
self.assertNotEqual(hash(a), hash(b))
165+
166+
def test_usable_in_set(self):
167+
"""MFCConfig should be usable in a set."""
168+
from ..state import MFCConfig
169+
170+
s = {MFCConfig(), MFCConfig(debug=True)}
171+
self.assertEqual(len(s), 2)
172+
self.assertIn(MFCConfig(), s)
173+
174+
def test_usable_as_dict_key(self):
175+
"""MFCConfig should be usable as a dict key."""
176+
from ..state import MFCConfig
177+
178+
d = {MFCConfig(): "default", MFCConfig(debug=True): "debug"}
179+
self.assertEqual(d[MFCConfig()], "default")
180+
181+
145182
if __name__ == "__main__":
146183
unittest.main()

0 commit comments

Comments
 (0)