From 26ff06167677b8ff3a35166cbcd9d19bd80324e3 Mon Sep 17 00:00:00 2001 From: Amethyst Reese Date: Tue, 9 Dec 2025 18:26:36 -0800 Subject: [PATCH] Reorganize suppression documentation, document range suppressions --- docs/linter.md | 129 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/docs/linter.md b/docs/linter.md index 1f3e4f22b5..a010ec6052 100644 --- a/docs/linter.md +++ b/docs/linter.md @@ -279,10 +279,22 @@ Conversely, the following configuration would only enable fixes for `F401`: Ruff supports several mechanisms for suppressing lint errors, be they false positives or permissible violations. -To omit a lint rule entirely, add it to the "ignore" list via the [`lint.ignore`](settings.md#lint_ignore) +### Configuration + +To omit a lint rule everywhere, add it to the "ignore" list via the [`lint.ignore`](settings.md#lint_ignore) setting, either on the command-line or in your `pyproject.toml` or `ruff.toml` file. -To suppress a violation inline, Ruff uses a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html). +To omit a lint rule within specific files based on file path prefixes or patterns, +see the [`lint.per-file-ignores`](settings.md#lint_per-file-ignores) setting. + +### Suppression comments + +Ruff supports multiple forms of suppression comments, including inline and file-level `noqa` +comments, and range suppressions. + +#### Inline suppressions + +Ruff supports a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html). To ignore an individual violation, add `# noqa: {code}` to the end of the line, like so: ```python @@ -314,6 +326,84 @@ import os # noqa: I001 import abc ``` +The full inline comment specification is as follows: + +- An inline blanket `noqa` comment is given by a case-insensitive match for + `#noqa` with optional whitespace after the `#` symbol, followed by either: the + end of the comment, the beginning of a new comment (`#`), or whitespace + followed by any character other than `:`. +- An inline rule suppression is given by first finding a case-insensitive match + for `#noqa` with optional whitespace after the `#` symbol, optional whitespace + after `noqa`, and followed by the symbol `:`. After this we are expected to + have a list of rule codes which is given by sequences of uppercase ASCII + characters followed by ASCII digits, separated by whitespace or commas. The + list ends at the last valid code. We will attempt to interpret rules with a + missing delimiter (e.g. `F401F841`), though a warning will be emitted in this + case. + +#### Range suppressions + +To ignore one or more violations within a range or block of code, a "disable" comment +followed by a matching "enable" comment can be used, like so: + +```python +# ruff: disable[E501] +VALUE_1 = "Lorem ipsum dolor sit amet ..." +VALUE_2 = "Lorem ipsum dolor sit amet ..." +VALUE_3 = "Lorem ipsum dolor sit amet ..." +# ruff: enable[E501] +``` + +To define a range, both the "disable" and "enable" comments must have matching codes, +in the same order, as well as matching indentation levels within a logical block of code: + +```python +def foo(): + # ruff: disable[E741, F841] + i = 1 + # ruff: enable[E741, F841] +``` + +If no matching "enable" comment is found, a RUF10x violation will be raised for unmatched +range suppression, though Ruff will also treat this as an "implicit" range. The implicit +range is defined from the starting "disable" comment, until reaching a logical scope +indented less than the starting comment: + +```python +def foo(): + # ruff: disable[E741, F841] + i = 1 + if True: + O = 1 + l = 1 + +# implicit end of range +foo() +``` + +It is strongly suggested using explicit range suppressions, in order to prevent +accidental suppressions of violations, especially at global module scope. If implicit +range suppressions are desired, the RUF10x lint can be disabled, or an inline `noqa` +suppression can be added to the end of the "disable" comment. + +Range suppressions can not be used to enable or select rules that aren't already +selected by the project configuration or runtime flags. An "enable" comment can only +be used to terminate a preceding "disable" comment with identical codes. + +Unlike `noqa` suppressions, range suppressions do not support "blanket" suppression +of all violations. At least one violation code must be listed. + +The full range suppression comment specification is as follows: + +- An own-line comment starting with case sensitive `#ruff:`, with optional whitespace + after the `#` symbol and `:` symbol, followed by either `disable` or `enable` + to start or end a range respectively, immediately followed by `[`, any codes to + be suppressed, and ending with `]`. +- Codes to be suppressed must be separated by commas, with optional whitespace + before or after each code. + +#### File-level suppressions + To ignore all violations across an entire file, add the line `# ruff: noqa` anywhere in the file, preferably towards the top, like so: @@ -328,47 +418,30 @@ file, preferably towards the top, like so: # ruff: noqa: F841 ``` -Or see the [`lint.per-file-ignores`](settings.md#lint_per-file-ignores) setting, which enables the same -functionality from within your `pyproject.toml` or `ruff.toml` file. - Global `noqa` comments must be on their own line to disambiguate from comments which ignore violations on a single line. Note that Ruff will also respect Flake8's `# flake8: noqa` directive, and will treat it as equivalent to `# ruff: noqa`. -### Full suppression comment specification +The file-level suppression comment specification is as follows: -The full specification is as follows: - -- An inline blanket `noqa` comment is given by a case-insensitive match for - `#noqa` with optional whitespace after the `#` symbol, followed by either: the - end of the comment, the beginning of a new comment (`#`), or whitespace - followed by any character other than `:`. -- An inline rule suppression is given by first finding a case-insensitive match - for `#noqa` with optional whitespace after the `#` symbol, optional whitespace - after `noqa`, and followed by the symbol `:`. After this we are expected to - have a list of rule codes which is given by sequences of uppercase ASCII - characters followed by ASCII digits, separated by whitespace or commas. The - list ends at the last valid code. We will attempt to interpret rules with a - missing delimiter (e.g. `F401F841`), though a warning will be emitted in this - case. - A file-level exemption comment is given by a case-sensitive match for `#ruff:` or `#flake8:`, with optional whitespace after `#` and before `:`, followed by optional whitespace and a case-insensitive match for `noqa`. After this, the - specification is as in the inline case. + specification is as in the inline `noqa` suppressions above. -### Detecting unused suppression comments +### Detecting unused suppressions Ruff implements a special rule, [`unused-noqa`](https://docs.astral.sh/ruff/rules/unused-noqa/), -under the `RUF100` code, to enforce that your `noqa` directives are "valid", in that the violations -they _say_ they ignore are actually being triggered on that line (and thus suppressed). To flag -unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100`. +under the `RUF100` code, to enforce that your suppressions are "valid", in that the violations +they _say_ they ignore are actually being triggered and suppressed. To flag +unused suppression comments, run: `ruff check /path/to/file.py --extend-select RUF100`. -Ruff can also _remove_ any unused `noqa` directives via its fix functionality. To remove any -unused `noqa` directives, run: `ruff check /path/to/file.py --extend-select RUF100 --fix`. +Ruff can also _remove_ any unused suppression comments via its fix functionality. To remove any +unused suppressions, run: `ruff check /path/to/file.py --extend-select RUF100 --fix`. -### Inserting necessary suppression comments +### Inserting necessary suppressions Ruff can _automatically add_ `noqa` directives to all lines that contain violations, which is useful when migrating a new codebase to Ruff. To automatically add `noqa` directives to all