Skip to content

Replace linters and formatters with ruff#1275

Merged
mulkieran merged 8 commits intostratis-storage:masterfrom
mulkieran:replace-linters-and-formatters-with-ruff
May 1, 2026
Merged

Replace linters and formatters with ruff#1275
mulkieran merged 8 commits intostratis-storage:masterfrom
mulkieran:replace-linters-and-formatters-with-ruff

Conversation

@mulkieran
Copy link
Copy Markdown
Member

@mulkieran mulkieran commented Apr 6, 2026

@mulkieran mulkieran self-assigned this Apr 6, 2026
@mulkieran mulkieran moved this to In Progress (long term) in 2026March Apr 6, 2026
@mulkieran mulkieran removed this from 2026March Apr 11, 2026
@mulkieran mulkieran moved this to In Progress (long term) in 2026April Apr 11, 2026
@mulkieran mulkieran force-pushed the replace-linters-and-formatters-with-ruff branch 2 times, most recently from 95d86e3 to f321692 Compare April 28, 2026 17:51
@mulkieran
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Walkthrough

The PR migrates the project's code quality toolchain from separate tools (pylint, isort, black) to unified ruff linting and formatting. This involves updating CI workflows, build configuration, removing legacy linter configuration files, and replacing linter-specific suppression comments with ruff-compatible equivalents throughout the codebase.

Changes

Cohort / File(s) Summary
CI/Build Configuration
.github/workflows/main.yml, Makefile, pyproject.toml, .isort.cfg
Updated workflow and build targets to use ruff check and ruff format instead of pylint/black/isort. Added Ruff configuration in pyproject.toml (Python version, line length, lint rules I and PL, import sorting). Removed .isort.cfg entirely.
Source Code - Actions Module
src/stratis_cli/_actions/_bind.py, _connection.py, _constants.py, _crypt.py, _data.py, _debug.py, _list_filesystem.py, _list_pool.py, _logical.py, _physical.py, _pool.py, _stratis.py, _stratisd_version.py, _top.py, _utils.py
Replaced pylint: disable=import-outside-toplevel comments with # noqa: PLC0415 on local imports. Removed pylint: disable=too-few-public-methods from class declarations. Refactored multi-line signatures/calls into single-line equivalents. Added blank lines after module docstrings.
Source Code - Core Module
src/stratis_cli/__init__.py, _alerts.py, _constants.py, _error_reporting.py, _errors.py, _exit.py
Removed pylint suppression comments (super-init-not-called, too-few-public-methods, broad-exception-caught). Added blank lines after module docstrings. Reformatted method signatures and conditional expressions for consistency.
Source Code - Parser Module
src/stratis_cli/_parser/__init__.py, _debug.py, _encryption.py, _logical.py, _parser.py, _physical.py, _pool.py, _shared.py
Removed pylint: disable=too-few-public-methods from class declarations. Collapsed multi-line option/argument dictionaries and tuples into single-line equivalents. Simplified class inheritance declarations by removing pylint comments.
Source Code - Constants Module
src/stratis_cli/_stratisd_constants.py
Removed pylint suppressions for invalid-name and too-few-public-methods from enum and class declarations.
Test Files - Misc & Integration
tests/_misc.py, tests/integration/_keyutils.py, tests/integration/key/test_set.py, tests/integration/logical/test_*.py, tests/integration/physical/test_*.py, tests/integration/pool/test_*.py
Replaced pylint: disable=import-outside-toplevel with # noqa: PLC0415 on late imports. Removed protected-access and other pylint suppressions. Reformatted multi-line command_line list constructions and test method calls into single-line equivalents. Added blank lines after module docstrings.
Test Files - Unit & Parser
tests/integration/test_parser.py, tests/integration/test_stratis.py, tests/unit/test_constants.py
Removed pylint: disable=too-many-public-methods from test class declarations. Simplified multi-line assertions and patch.object() calls into single-line form. Replaced import-related pylint suppressions with # noqa: PLC0415.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

  • PR #1279: Updates CI/workflow and Makefile linting configuration, complementing the ruff migration in this PR.
  • PR #1206: Modifies repository CI configuration and Makefile targets, related to toolchain changes.
  • PR #1267: Modifies src/stratis_cli/_actions/_list_pool.py, which overlaps with formatting changes in this PR.

Suggested labels

trivial

Suggested reviewers

  • jbaublitz
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Replace linters and formatters with ruff' clearly and directly describes the main objective of the changeset, which is to replace pylint, isort, and black with ruff across the project.
Docstring Coverage ✅ Passed Docstring coverage is 94.44% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/stratis_cli/_errors.py (1)

46-50: ⚠️ Potential issue | 🟠 Major

Add # noqa: PLW0231 suppression to the __init__ method.

Ruff's Pylint rule selection (configured as select = ["I", "PL"] in pyproject.toml) enables PLW0231, which flags super().__init__() not being called. Since StratisCliNoDeviceSizeChangeError.__init__ intentionally skips this call (the class only provides a custom error message via __str__), the suppression is required to pass linting.

♻️ Example fix
-    def __init__(self):
+    def __init__(self):  # noqa: PLW0231
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stratis_cli/_errors.py` around lines 46 - 50, Add the Ruff Pylint
suppression to the StratisCliNoDeviceSizeChangeError.__init__ method by
appending "# noqa: PLW0231" to the method definition (so the linter knows the
missing super().__init__ call is intentional); ensure the suppression is placed
on the def line for __init__ in class StratisCliNoDeviceSizeChangeError so the
linter ignores PLW0231 for that method.
src/stratis_cli/_actions/_utils.py (1)

55-217: ⚠️ Potential issue | 🟠 Major

Restore the removed Ruff suppressions on these classes and exception handler.

The suppressions were removed in the recent commit, but the classes still only define __init__ and (for EncryptionInfo) a single additional method consistent(), which triggers Ruff's PLR0903 (too-few-public-methods). The get_pass function still has a bare except Exception: handler, which triggers PLW0703 (broad-exception-caught). With select = ["I", "PL"] in the Ruff configuration, these suppressions must be restored either as # noqa: PLR0903, # noqa: PLW0703 comments, or addressed by restructuring these classes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stratis_cli/_actions/_utils.py` around lines 55 - 217, Restore the Ruff
suppressions by re-adding the appropriate noqa comments: add "# noqa: PLR0903"
to the class definitions for EncryptionInfo, EncryptionInfoClevis,
EncryptionInfoKeyDescription, and Device (these classes intentionally only
define __init__ and a minimal method), and add "# noqa: PLR0903" where
appropriate if any other small data-holder classes were affected (e.g.,
PoolFeature if needed); also restore "# noqa: PLW0703" on the broad except in
get_pass (the bare "except Exception:" handler) so Ruff no longer flags PLW0703.
Ensure the comments are placed on the same line as the class or except statement
so they persist as suppressions for the identified symbols (EncryptionInfo,
EncryptionInfoClevis, EncryptionInfoKeyDescription, Device, and get_pass).
🧹 Nitpick comments (2)
pyproject.toml (1)

14-14: Consider broadening Ruff rule selection to include baseline correctness checks.

At Line 14, select = ["I", "PL"] restricts linting to only import sorting and pylint rules, which disables Ruff's F (Pyflakes) and E (pycodestyle) rules. While Pyright handles type checking, it does not fully replace Pyflakes coverage for issues like undefined names and unused imports. Since Makefile invokes bare ruff check with no CLI-level --select overrides, this narrow scope is the effective lint configuration.

Suggested config adjustment
 [tool.ruff.lint]
-select = ["I", "PL"]
+select = ["E4", "E7", "E9", "F", "I", "PL"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pyproject.toml` at line 14, The current Ruff configuration restricts rules
via the setting 'select = ["I", "PL"]', which disables important Pyflakes (`F`)
and pycodestyle (`E`) checks; update the pyproject.toml Ruff configuration to
include at least "F" and "E" (or remove the restrictive select entirely) so bare
`ruff check` invoked by the Makefile runs baseline correctness checks (undefined
names, unused imports, style errors) in addition to import sorting and pylint
rules.
tests/integration/pool/test_bind.py (1)

27-27: Derive the loop bound from the new constant.

The new _MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED still leaves range(15) hard-coded, so this test can drift if the slot limit ever changes. Consider deriving the iteration bound from the constant as well.

[details]

♻️ Suggested refactor
-        for index in range(15):
+        for index in range(_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED + 1):

Also applies to: 170-184

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/pool/test_bind.py` at line 27, The loop bound is still
hard-coded as range(15) while the new constant
_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED governs the intended limit; replace
range(15) with range(_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED + 1) to preserve
current behavior (or range(_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED) if you
intended exclusive upper bound) in the occurrences in
tests/integration/pool/test_bind.py (update both the range(15) at line ~27 and
the one in the 170-184 block) so the test derives its iteration count from
_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Makefile`:
- Around line 8-14: Update the Makefile's fmt target so import-sorting runs
before formatting: modify the fmt recipe (target name "fmt") to first run "ruff
check --fix --select I" to apply isort-style fixes, then run "ruff format"; also
update the fmt-ci target if desired (currently "fmt-ci" runs "ruff format
--check") to include "ruff check --select I --check" behavior for CI consistency
by invoking "ruff check --select I --check" (or equivalent) before the format
check.
- Around line 4-6: The lint target removed explicit coverage for extensionless
entrypoints; update the Makefile's lint target (the "lint" recipe that currently
runs "ruff check") to include the extensionless script explicitly by invoking
ruff on "bin/stratis" in addition to the directory scan (e.g., run ruff check
against bin/stratis and the project paths) so that the extensionless entrypoint
"bin/stratis" is linted, then leave the existing pyright invocation as-is.

---

Outside diff comments:
In `@src/stratis_cli/_actions/_utils.py`:
- Around line 55-217: Restore the Ruff suppressions by re-adding the appropriate
noqa comments: add "# noqa: PLR0903" to the class definitions for
EncryptionInfo, EncryptionInfoClevis, EncryptionInfoKeyDescription, and Device
(these classes intentionally only define __init__ and a minimal method), and add
"# noqa: PLR0903" where appropriate if any other small data-holder classes were
affected (e.g., PoolFeature if needed); also restore "# noqa: PLW0703" on the
broad except in get_pass (the bare "except Exception:" handler) so Ruff no
longer flags PLW0703. Ensure the comments are placed on the same line as the
class or except statement so they persist as suppressions for the identified
symbols (EncryptionInfo, EncryptionInfoClevis, EncryptionInfoKeyDescription,
Device, and get_pass).

In `@src/stratis_cli/_errors.py`:
- Around line 46-50: Add the Ruff Pylint suppression to the
StratisCliNoDeviceSizeChangeError.__init__ method by appending "# noqa: PLW0231"
to the method definition (so the linter knows the missing super().__init__ call
is intentional); ensure the suppression is placed on the def line for __init__
in class StratisCliNoDeviceSizeChangeError so the linter ignores PLW0231 for
that method.

---

Nitpick comments:
In `@pyproject.toml`:
- Line 14: The current Ruff configuration restricts rules via the setting
'select = ["I", "PL"]', which disables important Pyflakes (`F`) and pycodestyle
(`E`) checks; update the pyproject.toml Ruff configuration to include at least
"F" and "E" (or remove the restrictive select entirely) so bare `ruff check`
invoked by the Makefile runs baseline correctness checks (undefined names,
unused imports, style errors) in addition to import sorting and pylint rules.

In `@tests/integration/pool/test_bind.py`:
- Line 27: The loop bound is still hard-coded as range(15) while the new
constant _MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED governs the intended limit;
replace range(15) with range(_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED + 1) to
preserve current behavior (or range(_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED) if
you intended exclusive upper bound) in the occurrences in
tests/integration/pool/test_bind.py (update both the range(15) at line ~27 and
the one in the 170-184 block) so the test derives its iteration count from
_MAX_LUKS_TOKEN_SLOTS_ALLOWED_TO_BE_USED.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1337ac38-749a-4e45-a08e-0d4e04095dc8

📥 Commits

Reviewing files that changed from the base of the PR and between 503b0d2 and 921ed0b.

📒 Files selected for processing (55)
  • .github/workflows/main.yml
  • .isort.cfg
  • Makefile
  • pyproject.toml
  • src/stratis_cli/__init__.py
  • src/stratis_cli/_actions/_bind.py
  • src/stratis_cli/_actions/_connection.py
  • src/stratis_cli/_actions/_constants.py
  • src/stratis_cli/_actions/_crypt.py
  • src/stratis_cli/_actions/_data.py
  • src/stratis_cli/_actions/_debug.py
  • src/stratis_cli/_actions/_list_filesystem.py
  • src/stratis_cli/_actions/_list_pool.py
  • src/stratis_cli/_actions/_logical.py
  • src/stratis_cli/_actions/_physical.py
  • src/stratis_cli/_actions/_pool.py
  • src/stratis_cli/_actions/_stratis.py
  • src/stratis_cli/_actions/_stratisd_version.py
  • src/stratis_cli/_actions/_top.py
  • src/stratis_cli/_actions/_utils.py
  • src/stratis_cli/_alerts.py
  • src/stratis_cli/_constants.py
  • src/stratis_cli/_error_reporting.py
  • src/stratis_cli/_errors.py
  • src/stratis_cli/_exit.py
  • src/stratis_cli/_parser/__init__.py
  • src/stratis_cli/_parser/_debug.py
  • src/stratis_cli/_parser/_encryption.py
  • src/stratis_cli/_parser/_logical.py
  • src/stratis_cli/_parser/_parser.py
  • src/stratis_cli/_parser/_physical.py
  • src/stratis_cli/_parser/_pool.py
  • src/stratis_cli/_parser/_shared.py
  • src/stratis_cli/_stratisd_constants.py
  • tests/_misc.py
  • tests/integration/_keyutils.py
  • tests/integration/key/test_set.py
  • tests/integration/logical/test_cancel_revert.py
  • tests/integration/logical/test_debug.py
  • tests/integration/logical/test_list.py
  • tests/integration/logical/test_schedule_revert.py
  • tests/integration/physical/test_debug.py
  • tests/integration/physical/test_list.py
  • tests/integration/pool/test_add.py
  • tests/integration/pool/test_bind.py
  • tests/integration/pool/test_create.py
  • tests/integration/pool/test_debug.py
  • tests/integration/pool/test_encryption.py
  • tests/integration/pool/test_explain.py
  • tests/integration/pool/test_init_cache.py
  • tests/integration/pool/test_list.py
  • tests/integration/pool/test_stop.py
  • tests/integration/test_parser.py
  • tests/integration/test_stratis.py
  • tests/unit/test_constants.py
💤 Files with no reviewable changes (3)
  • tests/integration/_keyutils.py
  • src/stratis_cli/_actions/_connection.py
  • .isort.cfg

Comment thread Makefile
Comment thread Makefile
@mulkieran mulkieran force-pushed the replace-linters-and-formatters-with-ruff branch 2 times, most recently from 1ada506 to 8708bd4 Compare April 29, 2026 00:31
@mulkieran mulkieran moved this from In Progress (long term) to In Progress in 2026April Apr 29, 2026
Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
ruff and pyright do just as well without PYTHONPATH specified.

Signed-off-by: mulhern <amulhern@redhat.com>
@mulkieran mulkieran force-pushed the replace-linters-and-formatters-with-ruff branch from 8708bd4 to 5a35d69 Compare April 29, 2026 00:41
@mulkieran mulkieran moved this from In Progress to In Review in 2026April Apr 29, 2026
@mulkieran mulkieran marked this pull request as ready for review April 29, 2026 14:22
The placement of the noqa annotations was blocking other transformations.

Signed-off-by: mulhern <amulhern@redhat.com>
Signed-off-by: mulhern <amulhern@redhat.com>
@mulkieran mulkieran merged commit dc1711a into stratis-storage:master May 1, 2026
9 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Done in 2026April May 1, 2026
@mulkieran mulkieran deleted the replace-linters-and-formatters-with-ruff branch May 1, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants