summary-terminal-punctuation (PDF301)¶
PDF300 summary-trailing-period
Next rule →PDF302 non-imperative-summary
Part of the PDF rule category.
View source · View documentation source · Search issues
Fix is sometimes available.
Rule is ignored if docstring-convention is pep257 or numpy.
What it does¶
Checks that the docstring summary punctuation target ends with terminal punctuation: a period, question mark, exclamation point, or Unicode ellipsis (\u2026).
The target is the final non-adornment line of the first logical summary paragraph. Empty docstrings, parser-recognized section-only docstrings, reST field-only docstrings under the reST convention, and targets ending with a backslash are skipped. Underlined title-style summaries are skipped when docstring-parse-headings is enabled. The automatic fix only inserts a period at the end of the trimmed target line; summaries ending with ,, :, or ; are reported but not changed.
Why is this useful?¶
Terminal punctuation keeps summary lines sentence-like without forcing every valid question or exclamation into a period.
Ruff compatibility¶
This rule replaces Ruff's D415. Use PDF300 for the stricter period-only form. Unlike Ruff's unsafe fix, this rule does not report or fix underlined title-style summaries when heading parsing is enabled.
Examples¶
Missing terminal punctuation is fixed by inserting a period:
def value():
"""Return the value"""
def value():
"""Return the value."""
Periods, question marks, exclamation points, and Unicode ellipses are all valid terminal punctuation:
def statement():
"""Return the value."""
def question():
"""Return the value?"""
def exclamation():
"""Return the value!"""
def ellipsis():
"""Return the value\u2026"""
For multi-line summaries, the target is the final non-adornment line of the first summary paragraph:
def multiline():
"""Return the value
after processing
"""
def multiline():
"""Return the value
after processing.
"""
Commas, colons, and semicolons are reported but not changed because adding a period would produce questionable punctuation:
def comma():
"""Return the value,"""
def colon():
"""Return the value:"""
def semicolon():
"""Return the value;"""
PDF301: Line 2: Docstring summary should end with terminal punctuation
PDF301: Line 6: Docstring summary should end with terminal punctuation
PDF301: Line 10: Docstring summary should end with terminal punctuation
Empty docstrings, parser-recognized section-only docstrings, and summaries ending with a backslash are skipped. With heading parsing enabled, underlined title-style summaries are also skipped. Recognized NumPy section headings such as Parameters followed by an underline are section headers, not summaries:
docstring-convention = "numpy"
def empty():
""""""
def title():
"""Result summary
==============
"""
def numpy_section_only(value):
"""Parameters
----------
value : int
"""
def backslash():
"""Path C:\\"""
reST field-only docstrings are skipped under the reST convention:
docstring-convention = "rest"
def rest_field(value):
""":param value: Description"""
When heading parsing is disabled, an underlined title-style summary is treated as summary text, and the underline adornment is not the punctuation target:
docstring-parse-headings = false
def title():
"""Result summary
==============
"""
def title():
"""Result summary.
==============
"""
Options¶
None.
PDF300 summary-trailing-period
Next rule →PDF302 non-imperative-summary