noqa-justification (KNQ001)¶
noqa justification
What it does¶
Requires every # noqa comment to carry a reason. The reason is any text after the directive in the same comment (leading #, - and : are ignored, but it needs at least one letter or digit). The # noqa: CODE # reason form is recommended because it reads the same to every tool that parses the comment. Only real comments count: # noqa inside a string literal is not flagged. Opt-in: the rule is not run by default; enable it with extend-select = ["KNQ001"] in [tool.konform.lint] (or --extend-select KNQ001).
Why is this bad?¶
A bare suppression hides a violation without recording why that is fine. Months later nobody knows whether it is still needed or safe to remove. A short reason makes the exception reviewable.
Example¶
Use instead:
from os.path import join # noqa: KIS001 # re-exported for plugins
value = compute() # noqa: KPT010 - generated code
Placeholder reasons¶
A reason that only repeats a placeholder is flagged too. The whole reason has to match (ignoring case, spacing and a trailing ./!), so todo: drop in v3 or ok for generated code are fine. Tighten the list in [tool.konform.lint.noqa-justification]:
[tool.konform.lint.noqa-justification]
extend-placeholder-reasons = ["legacy", "needed"] # add to the defaults
# placeholder-reasons = ["ok", "todo"] # ... or replace them ([] = off)
Minimum length¶
A reason needs at least 3 letters (ab or #123 alone are flagged), and a reason that is one repeated character (xxxx, 1111, a a a) is rejected. Both are configurable:
[tool.konform.lint.noqa-justification]
min-reason-letters = 5 # default 3; 0 = no minimum
reject-repeated-characters = false # default true
Exempt codes¶
Some suppressions explain themselves, such as F401 on a re-export or E501 on a long URL. List those codes (prefixes, like # noqa) and their comments need no reason:
The comment is only exempt when every listed code is. # noqa: F401, KIS001 still needs a reason, and a bare # noqa is never exempt. To exempt whole files instead (say __init__.py), use per-file-ignores: "**/__init__.py" = ["KNQ001"].
Suppressing and fixing¶
This rule cannot be suppressed with # noqa (not even # noqa: KNQ001), and --ignore-noqa does not affect it. Turn it off with ignore or per-file-ignores instead. It is not fixable. konform check --add-noqa --noqa-reason "..." fills in a missing reason on the comments it flags (see Baselining).
Options¶
Configured in [tool.konform.lint.noqa-justification].
| Option | Type | Default | Description |
|---|---|---|---|
level |
"warning" \| "error" |
"error" |
Severity of violations. Set warning to roll the rule out gradually. |
placeholder-reasons |
list[str] |
["ok", "fine", "todo", "fixme", "tbd", "wip", "later", "fix later", "n/a", "ignore", "noqa"] |
Reasons that say nothing. Replaces the defaults; [] turns the check off. |
extend-placeholder-reasons |
list[str] |
[] |
Added to the placeholder list (default or replaced). |
min-reason-letters |
int |
3 |
Letters a reason needs; 0 = no minimum. |
reject-repeated-characters |
bool |
true |
Reject a reason made of one repeated character (xxxx). |
exempt-codes |
list[str] |
[] |
Code prefixes whose # noqa comments need no reason. |