Skip to content

Respect Ruff rule code hierarchy in select/ignore lists#1527

Merged
nathanjmcdougall merged 6 commits into
mainfrom
copilot/respect-ruff-rule-hierarchy
Mar 25, 2026
Merged

Respect Ruff rule code hierarchy in select/ignore lists#1527
nathanjmcdougall merged 6 commits into
mainfrom
copilot/respect-ruff-rule-hierarchy

Conversation

Copilot AI commented Mar 25, 2026

Copy link
Copy Markdown
Contributor
  • Add is_rule_covered_by() and reconcile_rules() helpers in _tool/rule.py
  • Introduce RuleReconciliation frozen dataclass (replaces tuple return)
  • Update select_rules / ignore_rules in _tool/base.py to use reconciliation
  • Update ignore_rules_in_glob in _tool/impl/base/ruff.py to use reconciliation
  • Fix bug: startswith was too crude — now requires a digit boundary after prefix match (e.g. F covers F101 but not FLY)
  • Add tests for cross-group scenarios (FLY vs F, FLY001 vs F, F101 vs F1)
  • Run full static checks and verify
Original prompt

This section details on the original issue you should resolve

<issue_title>Respect Ruff rule code hierarchy</issue_title>
<issue_description>If Ruff selection contains "ALL" then we're already selecting all rules! There's not need to explicitly select another rule, it just gets "absorbed" into this "wildcard" style rule.

Similarly, if we want to select a specific rule code like TC001 then if there's already the rule code group like TC then there's no point adding it - we shouldn't.

It also goes the other way. We should replace a less general rule with a more general one. If we want to select TC and there's already TC001 then we should replace TC001 with TC.

All these principles also apply to ignores! And per-file ignores! Any time there's a list of ruff rules.

We should probably keep the current level of abstraction which manages the raw rule lists, but basically move that into helper methods, and so we can add some smart logic on top that manages the hierarchy between rule codes.

It is safe to assume that all rule codes follow this pattern - not just Ruff.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 25, 2026 03:12
…nore_rules_in_glob

- Add is_rule_covered_by() and reconcile_rules() helpers to rule.py
- Modify select_rules() and ignore_rules() in base.py to use hierarchy
- Modify ignore_rules_in_glob() in ruff.py to use hierarchy
- Add comprehensive tests for helper functions and integration behavior

Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com>
Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/880731be-ca47-4857-9975-4db0116718e6
Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com>
Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/880731be-ca47-4857-9975-4db0116718e6
Copilot AI changed the title [WIP] Refactor Ruff rule selection logic Respect Ruff rule code hierarchy in select/ignore lists Mar 25, 2026
Copilot AI requested a review from nathanjmcdougall March 25, 2026 03:16
Comment thread src/usethis/_tool/base.py Outdated
…aclass

Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com>
Agent-Logs-Url: https://github.com/usethis-python/usethis-python/sessions/f83674c7-4186-41aa-a4e8-babef65b8bb6
@codspeed-hq

codspeed-hq Bot commented Mar 25, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 2 untouched benchmarks


Comparing copilot/respect-ruff-rule-hierarchy (794435e) with main (f1eaa76)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (ceded75) during the generation of this report, so f1eaa76 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves how Ruff-like rule code lists are managed by respecting prefix-based hierarchy (e.g., TC subsumes TC001, ALL subsumes everything), preventing redundant entries and replacing subsumed specific rules when broader rules are introduced.

Changes:

  • Added rule hierarchy helpers in _tool/rule.py (is_rule_covered_by, reconcile_rules, and RuleReconciliation).
  • Updated _tool/base.py (select_rules, ignore_rules) to use reconciliation (including removing subsumed existing rules).
  • Updated Ruff per-file ignores handling to apply the same reconciliation logic, and added targeted tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/usethis/_tool/rule.py Introduces reusable hierarchy + reconciliation primitives for rule list updates.
src/usethis/_tool/base.py Applies reconciliation to global select/ignore rule mutations (adds + removes).
src/usethis/_tool/impl/base/ruff.py Applies reconciliation to Ruff per-file-ignores updates.
tests/usethis/_tool/test_rule.py Adds unit tests for hierarchy detection and reconciliation behavior.
tests/usethis/_tool/impl/base/test_ruff.py Adds integration-style tests validating Ruff config updates (select/ignore/per-file-ignores).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@nathanjmcdougall

Copy link
Copy Markdown
Collaborator

@copilot there's a bug - you're assuming with the current logic that F is a grouping around FLY for example. These are separate rule codes. This sort of "startswith" logic is too crude. Add tests.

F101 is a subrule of F1
but FLY is not a subrule of F
nor is FLY001 a subrule of F

Copilot AI commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

@copilot there's a bug - you're assuming with the current logic that F is a grouping around FLY for example. These are separate rule codes. This sort of "startswith" logic is too crude. Add tests....

Fixed in 794435e. The is_rule_covered_by now requires a digit boundary after the prefix match: F covers F101 (next char 1 is a digit) but not FLY (next char L is a letter). Added tests for FLY vs F, FLY001 vs F, and F101 vs F1.

Copilot AI requested a review from nathanjmcdougall March 25, 2026 20:14
@codecov

codecov Bot commented Mar 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@nathanjmcdougall nathanjmcdougall merged commit 2367a21 into main Mar 25, 2026
20 checks passed
@nathanjmcdougall nathanjmcdougall deleted the copilot/respect-ruff-rule-hierarchy branch March 25, 2026 20:27
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.

Respect Ruff rule code hierarchy

3 participants