Skip to content

Rule suppressions

This document specifies how pydocfmt source comments suppress pydocformatter rule findings and automatic fixes. Bracketed pydocfmt suppression payloads accept selectors such as PDF101, docstring-reflow, PDF, PCF000, PCF, and ALL.

Rule suppression directives in source code filter both check findings and automatic fixes. A suppressed finding is not reported, and a suppressed fix is not applied.

# noqa

Bare # noqa follows the conventional same-line shape used by Python tooling. It suppresses pydocfmt findings on the physical line where it appears. For PDF findings, an inline comment after any string token in a docstring expression covers the complete expression, including when more implicitly concatenated tokens follow on later lines. PCF findings remain line-local. Ordinary string expressions do not receive complete-expression PDF coverage, so directives on them retain normal same-line behavior.

Blanket # noqa is not audited by PCF101:

select = ["PCF001", "PCF101"]
value = compute() # noqa

Explicit # noqa: ... payloads suppress known pydocformatter code selectors in the payload. Rule names are not accepted in generic noqa comments, and foreign codes are ignored by pydocfmt:

select = ["PDF101", "PCF101"]
line-length = 48
"""This is a long module summary that needs wrapping into more than one physical line."""  # noqa: F401, PDF101

Foreign-only # noqa payloads do not suppress pydocfmt findings:

select = ["PDF101"]
line-length = 48
"""This is a long module summary that needs wrapping into more than one physical line."""  # noqa: F401
"""This is a long module summary that needs
wrapping into more than one physical line."""  # noqa: F401

A standalone # noqa above a docstring is still line-local. It does not attach to the following docstring:

select = ["PDF101"]
line-length = 48
# noqa: PDF101
"""This is a long module summary that needs wrapping into more than one physical line."""
# noqa: PDF101
"""This is a long module summary that needs
wrapping into more than one physical line."""

Malformed or non-conventional #noqa comments are not source suppressions until PCF100 normalizes them. In one fixing run, later rules still see the original source state, so a normalized directive suppresses later runs, not earlier findings in the same pass:

select = ["PCF001", "PCF100"]
value = compute()#noqa
value = compute()  # noqa

File-level # pydocfmt

Standalone # pydocfmt: noqa suppresses all pydocfmt findings in the file:

select = ["PDF101", "PCF001", "PCF101"]
line-length = 48
# pydocfmt: noqa
def function():
    """This is a long summary that needs wrapping into more than one physical line."""

value = 1 # trailing

Standalone # pydocfmt: noqa: ... and # pydocfmt: file-ignore[...] suppress matching selectors for the whole file, regardless of where the directive appears. The noqa form remains code-only, while file-ignore also accepts exact canonical names:

select = ["PDF101", "PCF101"]
line-length = 48
def first():
    """This is a long summary that needs wrapping into more than one physical line."""

# pydocfmt: file-ignore[docstring-reflow]

def second():
    """This is another long summary that needs wrapping into more than one physical line."""

Prefix selectors match all rules under that prefix:

select = ["PDF101", "PDF104", "PCF101"]
line-length = 48
# pydocfmt: file-ignore[PDF]
def function():
    """   This is a long summary that needs wrapping into more than one physical line."""

Local # pydocfmt: ignore[...]

Standalone # pydocfmt: ignore[...] attaches to the immediately following physical line. For docstrings, the target is the following docstring expression when that line begins its first string token. A delimiter-only opening-parenthesis line does not attach the directive to string tokens on later lines. An attached directive also suppresses diagnostics semantically owned by that docstring, even when the diagnostic is reported on a signature or body line:

select = ["PDF101", "PCF101"]
line-length = 48
def generated_function():
    # pydocfmt: ignore[docstring-reflow]
    """This is a long generated summary that needs to stay on one physical source line."""
select = ["PDF502", "PCF101"]
docstring-convention = "google"
docstring-missing-documentation = "all-docstrings"
def generated_function():
    # pydocfmt: ignore[PDF502]
    """Return a generated value."""
    return 1

Adjacent local directives share one following target:

select = ["PDF101", "PDF104", "PCF101"]
line-length = 48
def generated_function():
    # pydocfmt: ignore[PDF101]
    # pydocfmt: ignore[PDF104]
    """   This is a long generated summary that needs to stay on one physical source line."""

For standalone comments, the target is the following contiguous standalone comment run:

select = ["PCF000", "PCF101"]
line-length = 42
# pydocfmt: ignore[PCF000]
# This generated comment needs to stay exactly as emitted by the schema exporter.
# It is part of the same generated comment block.

The comment target stops at blank lines, indentation changes, protected comments, and empty or hash-only comments. Here the local directive suppresses only the first comment run, so the later run is still formatted:

select = ["PCF000"]
line-length = 42
# pydocfmt: ignore[PCF000]
# This generated comment needs to stay exactly as emitted by the schema exporter.

# This ordinary comment can still be wrapped by pydocfmt because it is a new run.
# pydocfmt: ignore[PCF000]
# This generated comment needs to stay exactly as emitted by the schema exporter.

# This ordinary comment can still be
# wrapped by pydocfmt because it is a new
# run.

For trailing comments, the target is the following physical line's trailing comment. This is the usual way to keep an explanatory trailing comment inline when PCF002 would otherwise extract it:

select = ["PCF002", "PCF101"]
line-length = 44
# pydocfmt: ignore[PCF002]
total = calculate_total(order)  # Generated field copy must stay near the assignment for the importer.

Inline # pydocfmt: ignore[...] suppresses findings on its own physical line. For PDF findings, placing it after any component string token covers the complete implicitly concatenated docstring expression. The expression must be a recognized primary or supported attached attribute docstring; ordinary string expressions do not gain expanded coverage. This does not expand PCF coverage, and a standalone directive between string tokens remains line-local:

select = ["PDF101", "PCF101"]
line-length = 48
"""This generated module summary must stay on one physical source line for the external checksum."""  # pydocfmt: ignore[PDF101] because generated

The same whole-expression coverage applies before the final component token:

select = ["PDF202", "PCF101"]
def generated_function():
    (""  # pydocfmt: ignore[PDF202]
     " ")

Selectors and audit behavior

Bracketed pydocfmt selector text is matched case-insensitively. Registered names resolve first and normalize to lowercase; code-shaped tokens normalize to uppercase and use the existing code-selector grammar; unknown name-shaped tokens normalize to lowercase; and invalid tokens retain their exact spelling. Valid selector prefixes such as PDF and PCF match all selected rules under that prefix, and ALL matches all selected pydocformatter rules. Names are exact only: there are no name prefixes, wildcards, or aliases. Generic # noqa and # pydocfmt: noqa payloads remain code-only.

PCF101 audits pydocfmt directives and known explicit pydocformatter selectors in # noqa: .... It does not audit blanket # noqa, foreign # noqa codes, or selectors for pydocformatter rules that are not selected in the current run.

An unused pydocfmt selector is reported when both PCF101 and the targeted rule are selected:

select = ["PCF000", "PCF101"]
# pydocfmt: ignore[PCF000]
# Short comment.
PCF101: Line 1: Suppression selector 'PCF000' did not suppress any findings

A registered name and its exact code share one semantic selector identity for suppression coverage and auditing. Repeats do not produce duplicate audit findings, but source spelling and multiplicity remain unchanged unless a selected fixing rule owns the rewrite. Broad selectors such as PDF, PDF5, and ALL remain distinct because their future-facing semantics differ:

select = ["PCF000", "PCF001", "PCF101"]
line-length = 42
# pydocfmt: ignore[PCF000, PCF001]
# This generated comment needs to stay exactly as emitted by the schema exporter.
PCF101: Line 1: Suppression selector 'PCF001' did not suppress any findings

Selectors for rules that are disabled in the current run are not reported as unused:

select = ["PCF101"]
line-length = 48
# pydocfmt: ignore[PDF101]
"""This is a long module summary that needs wrapping into more than one physical line."""

Known pydocformatter selectors in # noqa: ... are audited when explicit and unused:

select = ["PCF001", "PCF101"]
value = compute()  # noqa: F401, PCF001
PCF101: Line 1: Suppression selector 'PCF001' did not suppress any findings

Invalid or unknown pydocfmt selector payloads are reported by PCF101. Canonical-looking absent names are unknown, while text matching neither grammar is invalid:

select = ["PCF101"]
# pydocfmt: ignore[not-a-rule, bad!]
# Short comment.
PCF101: Line 1: Unknown pydocfmt suppression selector 'not-a-rule'
PCF101: Line 1: Invalid pydocfmt suppression selector 'bad!'

PCF100 canonicalizes recognized bracketed pydocfmt codes to uppercase and names to lowercase, uses comma-space separators, normalizes a whitespace-only selector list to [], removes an accepted trailing comma and terminal directive whitespace, and retains the first semantic code/name alias. Invalid tokens keep their exact spelling. Its Ruff normalization retains exact-text deduplication for ignore and file-ignore, while preserving the order and multiplicity of disable and enable payloads.

Suppression representation policies

PCF102 (rule-codes-in-suppression-comments) enforces names, while PCF103 (rule-names-in-suppression-comments) enforces codes. They are mutually incompatible and both require explicit selection by default. Broad selectors remain permitted under either policy because they have no exact alternative.

For bracketed pydocfmt: ignore and pydocfmt: file-ignore directives, both policies emit one finding per affected directive and safely convert every recognized exact local selector in one atomic fix. The targeted policy-only fix preserves selector order, rationale text, line endings, unrelated directive spelling and multiplicity, and malformed or foreign tokens while removing only aliases of identities touched by the conversion. PCF100 owns general list deduplication, so selecting it as well yields a globally normalized list independently of which representation policy runs first.

The policies also inspect Ruff's bracketed ignore, file-ignore, disable, and enable directives. PCF102 reports alphabetic-prefix-and-numeric-suffix tokens such as F401, while PCF103 reports safe name-shaped tokens such as unused-import. Broad Ruff selectors such as F, PLR, and ALL remain permitted under both policies because they have no exact alternative. Ruff findings are diagnostic-only because pydocformatter deliberately does not bundle or query Ruff's rule catalog, cannot prove code/name equivalence, and does not invoke Ruff. This is why both rules have Sometimes fix availability.

PCF102 and PCF103 opt into directive-line self-suppression through rule metadata. A selector for the active representation policy can therefore suppress that policy's finding on the same local bracket directive; other rules do not gain this exceptional coverage.

PCF101 can itself be suppressed:

select = ["PCF101"]
# pydocfmt: file-ignore[PCF101]
# pydocfmt: ignore[]
# Short comment.

Comments using the unrecognized pydocfmt actions disable[...] and enable[...] are protected as tool comments, but they do not suppress findings or fixes:

select = ["PDF101"]
line-length = 48
# pydocfmt: disable[PDF101]  # Unsupported by pydocfmt.
"""This is a long module summary that needs wrapping into more than one physical line."""
# pydocfmt: enable[PDF101]  # Unsupported by pydocfmt.
# pydocfmt: disable[PDF101]  # Unsupported by pydocfmt.
"""This is a long module summary that needs
wrapping into more than one physical line."""
# pydocfmt: enable[PDF101]  # Unsupported by pydocfmt.

Suppressed fixes

Suppression filtering is per finding, not per rule. A local directive can suppress one occurrence of a rule while another occurrence is still fixed:

select = ["PCF001", "PCF101"]
# pydocfmt: ignore[PCF001]
first = 1 # generated spacing
second = 2 # ordinary spacing
# pydocfmt: ignore[PCF001]
first = 1 # generated spacing
second = 2  # ordinary spacing