From 71625bf17c3cb0b77b340dda23020fca4ce293b6 Mon Sep 17 00:00:00 2001 From: Matthew Watkins Date: Thu, 30 Jul 2026 14:25:49 +0100 Subject: [PATCH] Chore: Pin ruff rule selection This repository runs the ruff hook with no ruff configuration, so it applies whatever ruff's default rule set happens to be. That default is not stable across releases: 59 rules across 2 categories in 0.15.22, 413 across 38 in 0.16.0. A routine pre-commit autoupdate crossing that boundary changes which rules run, on code nobody has touched. That is what currently fails the open autoupdate pull request here, on six findings: RUF100, I001, PIE810, PLW1510 and SIM102. The selection is deliberately narrow. It is the widest set this repository already satisfies, so pinning changes no behaviour today and both ruff 0.15.22 and 0.16.0 report all checks passing. It falls short of the organisation superset by "I" and "B", and both gaps are code changes rather than configuration ones: - "B" adds one B904 raise-without-from site in src/resolve_config_source.py, needing a judgement about which exception context to preserve. - "I" flags the test module import block, which deliberately calls sys.path.insert() before importing the module under test. That file is mirrored byte-for-byte with harden-runner-block-action and carries a "DO NOT EDIT IN ISOLATION" banner requiring paired pull requests, so it cannot be resolved from this repository alone. Folding either into a configuration chore would obscure both. The test per-file-ignores list rules that are not selected yet, so that widening the selection later does not immediately flag every test module. PLR0917 is there because tests stacking @patch decorators cannot satisfy it: unittest.mock injects each mock positionally, so a keyword-only signature is impossible rather than merely inconvenient. Co-authored-by: Claude Signed-off-by: Matthew Watkins --- .ruff.toml | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .ruff.toml diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..0ace3b8 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2026 The Linux Foundation + +# Pin the ruff rule set explicitly. +# +# Without a `select`, ruff applies its *default* rule set, and that +# default is not stable across releases: +# +# ruff 0.15.22 -> 59 rules across 2 categories (E, F) +# ruff 0.16.0 -> 413 rules across 38 categories +# +# A routine pre-commit autoupdate crossing that boundary changed which +# rules run and broke repositories across this organisation, on code +# nobody had touched. +# +# The selection below is deliberately narrow: it is the widest set this +# repository already satisfies, so pinning changes no behaviour today. +# It is a subset of the organisation superset +# ("E", "W", "F", "I", "B", "C4", "UP"), short by "I" and "B". Adopting +# those two is worthwhile but is a code change, not a configuration one: +# +# - "B" adds one B904 (raise-without-from) site in +# src/resolve_config_source.py, which needs a judgement about which +# exception context to preserve. +# - "I" flags the import block in the test modules, which deliberately +# call sys.path.insert() before importing the module under test. +# One of those files is mirrored byte-for-byte with a sibling +# repository and is marked "DO NOT EDIT IN ISOLATION", so touching +# it requires paired pull requests in both repositories. +# +# Both belong in their own reviewed change rather than riding along with +# a version bump. +# +# Note that this pins the rule set at CATEGORY level, not rule level. +# Ruff selectors are prefixes, so a future release adding new E* or F* +# rules would enable them here automatically. Pinning every rule code +# individually would be exhaustive and unmaintainable; the aim is to +# bound the blast radius, reducing "413 rules across 38 categories" +# back to five, not to freeze the set outright. +# +# `line-length` and `target-version` are intentionally left unset so +# ruff's own defaults continue to apply unchanged. + +[lint] +select = ["E", "W", "F", "C4", "UP"] + +ignore = [ + "E501", # line-too-long: the formatter owns line length + "B008", # function call in argument default: typer/click idiom +] + +[lint.per-file-ignores] +# Test suites legitimately break rules that matter in library code. +# +# None of these codes is reachable under the current `select`. They are +# listed anyway so that a later widening, to "S", "ARG" or "PL", does not +# immediately flag every test module. PLR0917 is the concrete case +# already seen elsewhere in this organisation: tests stacking @patch +# decorators cannot satisfy it, because unittest.mock injects its mocks +# positionally, so a keyword-only signature is impossible rather than +# merely inconvenient. +"tests/**/*.py" = ["S101", "ARG", "PLR0913", "PLR0917", "PLR2004"]