From de5594eb01c57581c57029cac13d8cab78c2020a Mon Sep 17 00:00:00 2001 From: Levon Becker Date: Wed, 29 Jul 2026 23:24:24 -0700 Subject: [PATCH] Restrict Pylint to just no-member, avoid duplicating Ruff's linting Pylint's astroid-based type inference is the only thing that catches attribute/method access that doesn't exist on a value's real type (no-member) - Ruff is purely AST-based and can't do this. Everything else Pylint could flag overlaps with Ruff and just adds noise plus runtime cost (measured ~30% faster on a small repo restricted to just this rule, since the inference machinery itself is the dominant cost either way). Co-Authored-By: Claude Sonnet 5 --- .github/instructions/python.instructions.md | 5 ++++- pyproject.toml | 23 ++------------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md index 86804de..0fc4566 100644 --- a/.github/instructions/python.instructions.md +++ b/.github/instructions/python.instructions.md @@ -9,7 +9,10 @@ Target: `>=3.14` (defined in `pyproject.toml`, pinned in `.python-version`) ## Style & Linting - **Ruff** enforces fast style/lint checks — run `uv run --no-sync invoke tests.rufflint` to check, `uv run --no-sync invoke ruff.fix` to auto-correct -- **Pylint** enforces deeper static analysis — run `uv run --no-sync invoke tests.pylint` (must score 10.00/10 to pass `invoke test`) +- **Pylint** is scoped to just `no-member` — the one check Ruff can't do (real type inference across installed + deps to catch attribute/method access that doesn't exist on the inferred type). Everything else Pylint could + flag is left to Ruff to avoid duplicate linting. Run `uv run --no-sync invoke tests.pylint` (must score 10.00/10 + to pass `invoke test` — see `[tool.pylint.messages_control]` in `pyproject.toml`) - Run `uv run --no-sync invoke fix` to auto-correct everything Ruff can fix, then format - Config lives in `pyproject.toml` under `[tool.ruff]` and `[tool.pylint]` - Disable a rule inline only when necessary, with a comment explaining why: diff --git a/pyproject.toml b/pyproject.toml index ae96cf6..be29246 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,27 +80,8 @@ ignore-paths = [ max-line-length = 100 [tool.pylint.messages_control] -disable = [ - "raw-checker-failed", - "bad-inline-option", - "locally-disabled", - "file-ignored", - "suppressed-message", - "useless-suppression", - "deprecated-pragma", - "use-symbolic-message-instead", - "use-implicit-booleaness-not-comparison-to-string", - "use-implicit-booleaness-not-comparison-to-zero", - "missing-module-docstring", - "missing-function-docstring", - "fixme", - "line-too-long", - "duplicate-code", - "relative-beyond-top-level", - "invalid-name", - "logging-fstring-interpolation", - "import-error", -] +disable = ["all"] +enable = ["no-member"] [tool.pylint.design] max-args = 15