Skip to content

too-many-blank-lines (PDF200)

Added in 1.1.0 Always fix By default Module and Fragment

Part of the PDF rule category.

View source · View documentation source · Search issues

Fix is always available.

What it does

Checks for excess blank logical lines inside safely rewritable docstrings.

A blank logical line is an evaluated docstring line with no non-whitespace content after docstring indentation has been mapped by pydocformatter's parser. Lines that contain only spaces, tabs, or other Unicode whitespace are blank for PDF200. PDF103 is responsible for normalizing the exact whitespace spelling of a retained blank line.

PDF200 keeps at most one blank line between adjacent semantic chunks. It removes semantic blank lines before the first chunk, removes semantic blank lines after the last chunk, and collapses runs of multiple blank lines between chunks to one blank line. It only removes excess blank lines; it does not insert missing blank lines between chunks that are already adjacent.

A chunk is any non-blank semantic block recognized by the docstring parser, including summaries, paragraphs, sections, section entries, reST fields under the reST convention, lists, headings, doctests, code fences, literal blocks, directives, tables, block quotes, and verbatim blocks. Blank lines inside opaque protected blocks are preserved, while blank-line runs around those protected blocks are still collapsed. Directive and literal-block bodies keep their internal blank lines, but trailing blank runs after their indented bodies are treated as exterior spacing between chunks.

With Google or NumPy conventions enabled, spacing is applied recursively inside recognized sections. Extra blank lines between a section header and its first body item are removed entirely, and extra blank lines between consecutive convention entries are removed entirely. Extra blank lines between adjacent whole sections collapse to one retained blank line. Other blank-line runs inside sections are still collapsed to one retained blank line unless they are inside opaque protected content.

The docstring-blank-line-after-last-section setting changes the trailing spacing rule for the final recognized Google or NumPy section. When enabled, PDF200 collapses trailing blank-line runs after the final recognized section to exactly one blank line. Otherwise, PDF200 removes blank lines after the final section. The trailing run is recognized from logical line order even when malformed indentation makes a nested terminal section own the blank block. The setting has no effect unless the active docstring-convention parses the final block as a Google or NumPy section.

PDF200 is neutral about delimiter placement. When the opening quotes already end a physical line, PDF200 preserves their first whitespace-only suffix line while removing any additional leading blanks; PDF106 and PDF107 own compact or separate opening placement. PDF200 likewise preserves one existing whitespace-only prefix before the closing quotes exactly as written while removing excess semantic trailing blanks; closing placement and indentation rules own any subsequent normalization.

Docstrings with no chunks are collapsed to an empty docstring when they can be safely rewritten. This includes multi-line blank-only docstrings and one-line whitespace-only docstrings.

PDF200 only rewrites safely mapped simple docstring literals. It skips concatenated docstrings and simple literals where evaluated lines cannot be mapped back to physical source lines safely, such as docstrings that contain escaped newline sequences. PDF000 can rewrite some of those skipped literals first, allowing PDF200 to run in a later rule pass when both rules are selected.

Why is this useful?

Predictable blank-line spacing keeps summaries, descriptions, sections, and protected examples visually distinct without adding vertical noise.

Ruff compatibility

This rule is intended to replace the fixable extra-blank-line cases covered by Ruff's D205; PDF203 handles summaries that still span multiple lines.

Examples

Extra blank lines before the first chunk, between chunks, and after the last chunk are removed:

def area(radius: float) -> float:
    """

    Return the area.


    The radius must be non-negative.

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

    The radius must be non-negative.
    """

PDF200 does not insert missing blank lines where none already exist:

def area(radius: float) -> float:
    """Return the area.
    The radius must be non-negative.
    """

Opening suffix and closing prefix lines are preserved without choosing a delimiter layout or normalizing their whitespace:

def function():
    """

    Summary.


    """

def odd_prefix():
    """Summary.
      """
def function():
    """
    Summary.
    """

def odd_prefix():
    """Summary.
      """

Blank-only docstrings collapse to empty docstrings:

def placeholder() -> None:
    """

    """

def inline(): """   """
def placeholder() -> None:
    """"""

def inline(): """"""

Blank lines inside protected blocks are preserved, while extra blank lines around protected blocks are collapsed:

def example() -> None:
    """Run the example.


    ```text
    first

    second
    ```


    .. note:: Title

        directive first


        directive second


    Example::

        literal first


        literal second


    Done.
    """
def example() -> None:
    """Run the example.

    ```text
    first

    second
    ```

    .. note:: Title

        directive first


        directive second

    Example::

        literal first


        literal second

    Done.
    """

With Google-style section parsing enabled, section headers and consecutive convention entries use compact spacing, while adjacent whole sections keep one blank line between them:

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

    Args:


        radius: Circle radius.


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

    Args:
        radius: Circle radius.

    Returns:
        float: Area.
    """

The final-section setting controls whether one trailing blank after the last recognized section is retained:

docstring-convention = "google"
docstring-blank-line-after-last-section = true
def area(radius: float) -> float:
    """Return the area.

    Args:
        radius: Circle radius.


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

    Args:
        radius: Circle radius.

    """

NumPy-style section parsing applies the same compact spacing after section underlines and keeps one blank line between adjacent whole sections:

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

    Parameters
    ----------


    radius : float
        Circle radius.


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

    Parameters
    ----------
    radius : float
        Circle radius.

    Returns
    -------
    float
        Area.
    """

reST fields under the reST convention use compact spacing between adjacent fields:

docstring-convention = "rest"
def value(first: int, second: int) -> int:
    """Return a value.

    :param first: First value.


    :param second: Second value.
    """
def value(first: int, second: int) -> int:
    """Return a value.

    :param first: First value.
    :param second: Second value.
    """

Generic structure settings control whether special-looking blocks are protected. With code fence parsing disabled, PDF200 can collapse blank lines inside fenced-looking text:

docstring-parse-code-fences = false
def example() -> None:
    """Summary.

    ```text
    first


    second
    ```
    """
def example() -> None:
    """Summary.

    ```text
    first

    second
    ```
    """

Concatenated docstrings and docstrings with escaped newlines are skipped because the exact source line ownership is ambiguous for this rule:

def escaped() -> None:
    """Summary.\n\n\nBody."""

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

When PDF000 is also selected outside this rule-specific example context, it can literalize escaped blank lines before PDF200 collapses them in a later rule pass.

Options