Skip to content

summary-too-long (PDF203)

Added in 1.0.0 Never fix By default

Part of the PDF rule category.

View source · View documentation source · Search issues

Fix is not available.

What it does

Checks docstrings whose parsed top-level summary still spans multiple logical lines after selected automatic fixes have run.

PDF203 reports only summary blocks. It does not report one-line summaries, paragraphs after a blank line, convention sections, recognized structures, blank-only docstrings, or docstrings without a parsed summary. Because the rule is diagnostic-only, it leaves source unchanged and reports a non-fixable finding.

When selected together with PDF101, short wrapped summaries can be reflowed before PDF203 checks the final source. When selected together with PDF201, recognized structures can be separated from a one-line summary before PDF203 checks. Summaries that remain multi-line after selected fixes are reported for human rewriting or for a human decision about whether a blank line is missing between the summary and description.

Parsing settings and the active convention affect what counts as a summary. Recognized structures such as list items, headings, doctests, directives, reST fields under the reST convention, block quotes, code fences, and tables are protected. Disabling the matching docstring-parse-* setting can make generic structure lines become part of the parsed summary and therefore reportable.

Why is this useful?

A multi-line summary can be ambiguous: it may be a long summary that needs rewriting by a human, or a missing blank line between the summary and description.

Ruff compatibility

This rule is intended to cover the non-fixable part of Ruff's D205 behavior after pydocformatter has normalized fixable blank-line spacing. Ruff's D205 cannot safely decide whether adjacent prose is a wrapped summary or a missing blank line; PDF203 reports that ambiguity without changing source.

Examples

PDF203 reports an ambiguous multi-line summary and does not change the source:

def area(radius: float) -> float:
    """Return the area for a circle
    after validating the radius.
    """
PDF203: Lines 2-3: Docstring summary spans 2 lines and does not fit on one line

When PDF203 is selected by itself, line-length does not make it reflow or suppress a multi-line summary:

line-length = 88
def area(radius: float) -> float:
    """Return the area
    for a circle.
    """
PDF203: Lines 2-3: Docstring summary spans 2 lines and does not fit on one line

Multiple docstring shapes can be reported in one file. Line numbers point to the mapped summary source lines, falling back to the physical docstring line for escaped newline summaries:

"""Module summary line
continued here."""

def concatenated() -> None:
    ("Summary line\n"
     "continuation line.")

def escaped() -> None:
    """Summary line\ncontinuation line."""
PDF203: Lines 1-2: Docstring summary spans 2 lines and does not fit on one line
PDF203: Lines 5-6: Docstring summary spans 2 lines and does not fit on one line
PDF203: Line 9: Docstring summary spans 2 lines and does not fit on one line

One-line summaries followed by a blank-line-separated body, paragraph, or recognized section are not reported:

docstring-convention = "google"
def body(radius: float) -> float:
    """Return the area.

    The radius is validated before the area is computed.
    """

def section(radius: float) -> float:
    """Return the area.

    Args:
        radius: Circle radius.
    """

Only the top-level summary block is diagnostic. Later multi-line paragraphs and section entries are not reported:

docstring-convention = "google"
def paragraph() -> None:
    """Summary.

    Body line one
    body line two.
    """

def section(value: int) -> None:
    """Summary.

    Args:
        value: Description line one
            continuation line.
    """

Recognized structures are protected by default, even if they appear at the start of a docstring:

def list_item() -> None:
    """- item
    continuation
    """

def fenced() -> None:
    """```python
    print(value)
    ```
    """

reST fields are protected under the reST convention, so a continued reST field is not a multi-line summary:

docstring-convention = "rest"
def value() -> int:
    """:returns: The computed value
    after validation.
    """

If the relevant structure parser is disabled, the same text can become a reportable multi-line summary:

docstring-parse-list-items = false
def list_item() -> None:
    """- item
    continuation
    """
PDF203: Lines 2-3: Docstring summary spans 2 lines and does not fit on one line

Ambiguous prose without a blank line after a one-line opening sentence is reported because it may be either a wrapped summary or a missing summary/body separator:

def area(radius: float) -> float:
    """Return the area.
    Validate the radius before computing it.
    """
PDF203: Lines 2-3: Docstring summary spans 2 lines and does not fit on one line

Options

None.