Skip to content

Enable the muff linter (muff check) with a rule set suited to this codebase #39

Closed

Description

@jsh9

Background

#37 replaced isort, cercis and flake8 with muff-format, pydoclint and a new set of pre-commit hooks, copied from jsh9/bootstrap2. Only the muff formatter runs:

  • The pre-commit config has only the muff-format hook.
  • The muff-format tox env runs muff format --diff.
  • Nothing runs muff check.

muff.toml contains a full [lint] section copied from bootstrap2 (extend-select with about 50 rule groups), but it is unused.

Before #37, CI also ran three flake8 envs (flake8-basic, flake8-misc, flake8-docstrings). Python linting is therefore reduced to pydoclint, which checks docstrings only. This issue is about adding a linter back.

Current numbers

These were measured with muff 0.15.20 and the current muff.toml on the #37 branch. They cover PySeismoSoil/ only, because muff.toml excludes tests/.

With the full bootstrap2 rule set: 1,597 violations (84 auto-fixable). Most come from rules that conflict with this codebase's conventions and public API:

Count Rule
330 N806: non-lowercase variable names (Vs, Tmax, G, ...)
171 + 171 FBT001 / FBT002: positional boolean arguments (show_fig=False, ...)
124 E501: line too long
102 PLR2004: magic numbers in comparisons
100 / 45 / 26 N803 / N802 / N801: non-lowercase argument, function and class names (Vs_Profile, ...)
81 UP031: % string formatting

Proposal

  1. Add the hook. Add id: muff-check from https://github.com/jsh9/muff-pre-commit, with args: [--config, muff.toml], to .pre-commit-config.yaml. Optionally also add a muff-check tox env (muff check --config=muff.toml PySeismoSoil) to the CI lint job. If you do, extend the sync-precommit-tox-versions hook so the env's muff pin stays in sync.
  2. Ignore the rules that conflict with the codebase's conventions in muff.toml, for example:
    ignore = [
      # ... existing entries ...
      "E501",                                     # muff-format handles code; long strings/URLs remain
      "FBT001", "FBT002", "FBT003",               # boolean positional args are part of the public API
      "N801", "N802", "N803", "N806", "N815", "N816", "N999",  # scientific naming (Vs, Tmax, Vs_Profile, ...)
      "PLR2004",                                  # magic numbers are common in physics formulas
    ]
    That leaves 523 violations. The largest groups are:
    • UP031 (81): % formatting
    • RET504 (39): unnecessary assignment before return
    • ANN001 (38): missing argument annotations
    • PTH118 (29): os.path.join
    • TC002 (26): imports used only for typing
    • PLR6201 (22): literal membership tests
    • PLR0915 (18): too many statements
    • PLR6104 (18): non-augmented assignment
    • RUF100 (18): unused noqa directives
    • PLC0415 (16): import outside top level
    • SLF001 (16): private member access
  3. Fix or ignore the rest, rule by rule. Some groups are worth fixing; others (e.g. PTH, ANN, TC, PLR6201) may be style preferences better added to ignore.

Possible first step

Start with roughly what flake8 used to check:

--select E,F,W,B,C4,ERA,Q,T10,ISC,RET,D
--ignore E501,D100,D104,D105,D107,D200,D205,D400

That gives only 55 violations:

  • 39 × RET504
  • 7 × D420
  • 5 × ERA001
  • 3 × B905
  • 1 × RET506

Then broaden the rule set gradually.

Related cleanups that would surface

  • Stale flake8 # noqa codes. muff reports 18 × RUF100 (unused noqa) and 7 × RUF102 (invalid rule code). These are leftovers from the flake8 setup:

    • codes for rules muff doesn't enable, e.g. E226, E501, R506, E731
    • codes muff doesn't know, e.g. LN001, W503, E800

    Most are auto-fixable.

  • RUF012 (mutable class default). This flags Site_Factors.Vs30_array, z1_array and PGA_array (lists used as class attributes). They are never mutated, so this is low risk. Switching them to tuples would also require changing the three '... %s' % Site_Factors.Vs30_array error messages, which break with a tuple.

  • tests/. It is currently excluded via extend-exclude = ["tests"] (on purpose in Modernize CI pipeline (muff-format, pydoclint, pre-commit); drop Python 3.10 #37), so the tests/* per-file ignores in muff.toml have no effect until that exclusion is removed.

This should be a separate PR from #37: unlike #37, it would change code beyond formatting.

Activity

  1. jsh9 commented on Oct 11, 2026

    @jsh9
    CollaboratorAuthor

    This was done in #56 ("Add muff linter (muff-check) and fix lint violations", merged 2026-10-07), with follow-ups in #70 and #72. Closing.

    What this issue proposed, and where it stands on main (b764057):

    1. Add the hook: muff-check from jsh9/muff-pre-commit (0.15.20) is in .pre-commit-config.yaml with --config muff.toml. The CI lint job runs it through tox -e pre-commit. Add muff linter (muff-check) and fix lint violations #56 added a separate muff-check tox env, and Run muff-check and muff-format only as pre-commit hooks #70 then removed it in favor of the pre-commit hook.
    2. Ignore the rules that conflict with the codebase's conventions: muff.toml ignores the naming rules N801, N802, N803, N806, N815 and N999. Add muff linter (muff-check) and fix lint violations #56 fixed the other suggested ignores instead of suppressing them:
      • FBT001/FBT002: boolean arguments are now keyword-only.
      • PLR2004: magic numbers became named constants.
      • E501: long lines were wrapped.
    3. Fix or ignore the rest: the remaining violations were fixed in PySeismoSoil/, the notebooks, scripts/ and docs/source/conf.py (Add muff linter (muff-check) and fix lint violations #56). tests/ was linted too, in Lint tests/ with muff-check; fix the lint violations #72. RUF is enabled, so the stale noqa codes (RUF100/RUF102) and RUF012 from the "Related cleanups" list are covered as well.

    Checked today: muff check --config muff.toml . with muff 0.15.20 on main reports All checks passed!.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions