diff --git a/crates/ruff/src/rules/pydocstyle/rules/blank_after_summary.rs b/crates/ruff/src/rules/pydocstyle/rules/blank_after_summary.rs index c655df13e0..8e939060dc 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/blank_after_summary.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/blank_after_summary.rs @@ -6,6 +6,40 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::AsRule; +/// ## What it does +/// Checks for docstring summary lines that are not separated from the docstring +/// description by one blank line. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that multi-line docstrings consist of "a summary line +/// just like a one-line docstring, followed by a blank line, followed by a +/// more elaborate description." +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// Sort the list in ascending order and return a copy of the +/// result using the bubble sort algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the +/// result using the bubble sort algorithm. +/// """ +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct BlankLineAfterSummary { num_lines: usize, diff --git a/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_class.rs b/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_class.rs index 6a71f725b4..3d4524d497 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_class.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_class.rs @@ -10,6 +10,37 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::{AsRule, Rule}; +/// ## What it does +/// Checks for docstrings on class definitions that are not preceded by a +/// blank line. +/// +/// ## Why is this bad? +/// Use a blank line to separate the docstring from the class definition, for +/// consistency. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is disabled when using the `google`, +/// `numpy`, and `pep257` conventions. +/// +/// For an alternative, see [D211]. +/// +/// ## Example +/// ```python +/// class PhotoMetadata: +/// """Metadata about a photo.""" +/// ``` +/// +/// Use instead: +/// ```python +/// class PhotoMetadata: +/// +/// """Metadata about a photo.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// [D211]: https://beta.ruff.rs/docs/rules/blank-line-before-class #[violation] pub struct OneBlankLineBeforeClass { lines: usize, @@ -26,6 +57,44 @@ impl AlwaysAutofixableViolation for OneBlankLineBeforeClass { } } +/// ## What it does +/// Checks for class methods that are not separated from the class's docstring +/// by a blank line. +/// +/// ## Why is this bad? +/// [PEP 257] recommends the use of a blank line to separate a class's +/// docstring its methods. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `google` +/// convention, and disabled when using the `numpy` and `pep257` conventions. +/// +/// ## Example +/// ```python +/// class PhotoMetadata: +/// """Metadata about a photo.""" +/// def __init__(self, file: Path): +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// class PhotoMetadata: +/// """Metadata about a photo.""" +/// +/// def __init__(self, file: Path): +/// ... +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct OneBlankLineAfterClass { lines: usize, @@ -42,6 +111,37 @@ impl AlwaysAutofixableViolation for OneBlankLineAfterClass { } } +/// ## What it does +/// Checks for docstrings on class definitions that are preceded by a blank +/// line. +/// +/// ## Why is this bad? +/// Avoid introducing any blank lines between a class definition and its +/// docstring, for consistency. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `google`, +/// `numpy`, and `pep257` conventions. +/// +/// For an alternative, see [D203]. +/// +/// ## Example +/// ```python +/// class PhotoMetadata: +/// """Metadata about a photo.""" +/// ``` +/// +/// Use instead: +/// ```python +/// class PhotoMetadata: +/// +/// """Metadata about a photo.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// [D203]: https://beta.ruff.rs/docs/rules/one-blank-line-before-class #[violation] pub struct BlankLineBeforeClass { lines: usize, diff --git a/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_function.rs b/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_function.rs index 337d02b789..44bea30595 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_function.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/blank_before_after_function.rs @@ -12,6 +12,31 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::{AsRule, Rule}; +/// ## What it does +/// Checks for docstrings on functions that are separated by one or more blank +/// lines from the function definition. +/// +/// ## Why is this bad? +/// Remove any blank lines between the function definition and its docstring, +/// for consistency. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// +/// """Return the mean of the given values.""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct NoBlankLineBeforeFunction { num_lines: usize, @@ -29,6 +54,33 @@ impl AlwaysAutofixableViolation for NoBlankLineBeforeFunction { } } +/// ## What it does +/// Checks for docstrings on functions that are separated by one or more blank +/// lines from the function body. +/// +/// ## Why is this bad? +/// Remove any blank lines between the function body and the function +/// docstring, for consistency. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// +/// return sum(values) / len(values) +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// return sum(values) / len(values) +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct NoBlankLineAfterFunction { num_lines: usize, diff --git a/crates/ruff/src/rules/pydocstyle/rules/capitalized.rs b/crates/ruff/src/rules/pydocstyle/rules/capitalized.rs index 7ae7030663..1e5c110c47 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/capitalized.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/capitalized.rs @@ -9,6 +9,29 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::AsRule; +/// ## What it does +/// Checks for docstrings that do not start with a capital letter. +/// +/// ## Why is this bad? +/// The first character in a docstring should be capitalized for, grammatical +/// correctness and consistency. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """return the mean of the given values.""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct FirstLineCapitalized { first_word: String, diff --git a/crates/ruff/src/rules/pydocstyle/rules/ends_with_period.rs b/crates/ruff/src/rules/pydocstyle/rules/ends_with_period.rs index a870568d5e..ba53386fee 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/ends_with_period.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/ends_with_period.rs @@ -11,6 +11,38 @@ use crate::docstrings::Docstring; use crate::registry::AsRule; use crate::rules::pydocstyle::helpers::logical_line; +/// ## What it does +/// Checks for docstrings in which the first line does not end in a period. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that the first line of a docstring is written in the +/// form of a command, ending in a period. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `numpy` and +/// `pep257` conventions, and disabled when using the `google` convention. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct EndsInPeriod; diff --git a/crates/ruff/src/rules/pydocstyle/rules/ends_with_punctuation.rs b/crates/ruff/src/rules/pydocstyle/rules/ends_with_punctuation.rs index bd6302cb9e..9e11eb1c8e 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/ends_with_punctuation.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/ends_with_punctuation.rs @@ -11,6 +11,37 @@ use crate::docstrings::Docstring; use crate::registry::AsRule; use crate::rules::pydocstyle::helpers::logical_line; +/// ## What it does +/// Checks for docstrings in which the first line does not end in a punctuation +/// mark, such as a period, question mark, or exclamation point. +/// +/// ## Why is this bad? +/// The first line of a docstring should end with a period, question mark, or +/// exclamation point, for grammatical correctness and consistency. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `google` +/// convention, and disabled when using the `numpy` and `pep257` conventions. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct EndsInPunctuation; diff --git a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs index a109e51ea5..87262ccce1 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/if_needed.rs @@ -8,6 +8,66 @@ use ruff_python_semantic::{Definition, Member, MemberKind}; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; +/// ## What it does +/// Checks for `@overload` function definitions that contain a docstring. +/// +/// ## Why is this bad? +/// The `@overload` decorator is used to define multiple compatible signatures +/// for a given function, to support type-checking. A series of `@overload` +/// definitions should be followed by a single non-decorated definition that +/// contains the implementation of the function. +/// +/// `@overload` function definitions should not contain a docstring; instead, +/// the docstring should be placed on the non-decorated definition that contains +/// the implementation. +/// +/// ## Example +/// ```python +/// from typing import overload +/// +/// +/// @overload +/// def factorial(n: int) -> int: +/// """Return the factorial of n.""" +/// +/// +/// @overload +/// def factorial(n: float) -> float: +/// """Return the factorial of n.""" +/// +/// +/// def factorial(n): +/// """Return the factorial of n.""" +/// +/// +/// factorial.__doc__ # "Return the factorial of n." +/// ``` +/// +/// Use instead: +/// ```python +/// from typing import overload +/// +/// +/// @overload +/// def factorial(n: int) -> int: +/// ... +/// +/// +/// @overload +/// def factorial(n: float) -> float: +/// ... +/// +/// +/// def factorial(n): +/// """Return the factorial of n.""" +/// +/// +/// factorial.__doc__ # "Return the factorial of n." +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [Python documentation: `typing.overload`](https://docs.python.org/3/library/typing.html#typing.overload) #[violation] pub struct OverloadWithDocstring; diff --git a/crates/ruff/src/rules/pydocstyle/rules/indent.rs b/crates/ruff/src/rules/pydocstyle/rules/indent.rs index d9d352dfcd..1f8762cae5 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/indent.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/indent.rs @@ -10,6 +10,38 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::{AsRule, Rule}; +/// ## What it does +/// Checks for docstrings that are indented with tabs. +/// +/// ## Why is this bad? +/// [PEP 8](https://peps.python.org/pep-0008/#tabs-or-spaces) recommends using +/// spaces over tabs for indentation. +/// +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct IndentWithSpaces; @@ -20,6 +52,39 @@ impl Violation for IndentWithSpaces { } } +/// ## What it does +/// Checks for under-indented docstrings. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that docstrings be indented to the same level as their +/// opening quotes. Avoid under-indenting docstrings, for consistency. +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble sort +/// algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct UnderIndentation; @@ -34,6 +99,39 @@ impl AlwaysAutofixableViolation for UnderIndentation { } } +/// ## What it does +/// Checks for over-indented docstrings. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that docstrings be indented to the same level as their +/// opening quotes. Avoid over-indenting docstrings, for consistency. +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the +/// bubble sort algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct OverIndentation; diff --git a/crates/ruff/src/rules/pydocstyle/rules/multi_line_summary_start.rs b/crates/ruff/src/rules/pydocstyle/rules/multi_line_summary_start.rs index 98a1eee00f..b470da5ea7 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/multi_line_summary_start.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/multi_line_summary_start.rs @@ -11,6 +11,46 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::{AsRule, Rule}; +/// ## What it does +/// Checks for docstring summary lines that are not positioned on the first +/// physical line of the docstring. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that multi-line docstrings consist of "a summary line +/// just like a one-line docstring, followed by a blank line, followed by a +/// more elaborate description." +/// +/// The summary line should be located on the first physical line of the +/// docstring, immediately after the opening quotes. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `google` +/// convention, and disabled when using the `numpy` and `pep257` conventions. +/// +/// For an alternative, see [D213]. +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """ +/// Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the +/// bubble sort algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// [D213]: https://beta.ruff.rs/docs/rules/multi-line-summary-second-line #[violation] pub struct MultiLineSummaryFirstLine; @@ -25,6 +65,46 @@ impl AlwaysAutofixableViolation for MultiLineSummaryFirstLine { } } +/// ## What it does +/// Checks for docstring summary lines that are not positioned on the second +/// physical line of the docstring. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that multi-line docstrings consist of "a summary line +/// just like a one-line docstring, followed by a blank line, followed by a +/// more elaborate description." +/// +/// The summary line should be located on the second physical line of the +/// docstring, immediately after the opening quotes and the blank line. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is disabled when using the `google`, +/// `numpy`, and `pep257` conventions. +/// +/// For an alternative, see [D212]. +/// +/// ## Example +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the +/// bubble sort algorithm. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: list[int]) -> list[int]: +/// """ +/// Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// [D212]: https://beta.ruff.rs/docs/rules/multi-line-summary-first-line #[violation] pub struct MultiLineSummarySecondLine; diff --git a/crates/ruff/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs b/crates/ruff/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs index 6345cbb9b0..384635ea61 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/newline_after_last_paragraph.rs @@ -10,6 +10,40 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::AsRule; +/// ## What it does +/// Checks for multi-line docstrings whose closing quotes are not on their +/// own line. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that the closing quotes of a multi-line docstring be +/// on their own line, for consistency and compatibility with documentation +/// tools that may need to parse the docstring. +/// +/// ## Example +/// ```python +/// def sort_list(l: List[int]) -> List[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the +/// bubble sort algorithm.""" +/// ``` +/// +/// Use instead: +/// ```python +/// def sort_list(l: List[int]) -> List[int]: +/// """Return a sorted copy of the list. +/// +/// Sort the list in ascending order and return a copy of the result using the bubble +/// sort algorithm. +/// """ +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct NewLineAfterLastParagraph; diff --git a/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs b/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs index 1ae23355ba..486df63860 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs @@ -8,6 +8,40 @@ use ruff_python_whitespace::UniversalNewlines; use crate::checkers::ast::Checker; use crate::docstrings::Docstring; +/// ## What it does +/// Checks for function docstrings that include the function's signature in +/// the summary line. +/// +/// ## Why is this bad? +/// [PEP 257] recommends against including a function's signature in its +/// docstring. Instead, consider using type annotations as a form of +/// documentation for the function's parameters and return value. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `google` and +/// `pep257` conventions, and disabled when using the `numpy` convention. +/// +/// ## Example +/// ```python +/// def foo(a, b): +/// """foo(a: int, b: int) -> list[int]""" +/// ``` +/// +/// Use instead: +/// ```python +/// def foo(a: int, b: int) -> list[int]: +/// """Return a list of a and b.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct NoSignature; diff --git a/crates/ruff/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs b/crates/ruff/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs index 6f4be82526..cd1d4ff3da 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/no_surrounding_whitespace.rs @@ -9,6 +9,28 @@ use crate::docstrings::Docstring; use crate::registry::AsRule; use crate::rules::pydocstyle::helpers::ends_with_backslash; +/// ## What it does +/// Checks for surrounding whitespace in docstrings. +/// +/// ## Why is this bad? +/// Remove surrounding whitespace from the docstring, for consistency. +/// +/// ## Example +/// ```python +/// def factorial(n: int) -> int: +/// """ Return the factorial of n. """ +/// ``` +/// +/// Use instead: +/// ```python +/// def factorial(n: int) -> int: +/// """Return the factorial of n.""" +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct SurroundingWhitespace; diff --git a/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs b/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs index d4d80dbdc2..3969452fce 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/non_imperative_mood.rs @@ -17,6 +17,39 @@ use crate::rules::pydocstyle::helpers::normalize_word; static MOOD: Lazy = Lazy::new(Mood::new); +/// ## What it does +/// Checks for docstring first lines that are not in an imperative mood. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that the first line of a docstring be written in the +/// imperative mood, for consistency. +/// +/// Hint: to rewrite the docstring in the imperative, phrase the first line as +/// if it were a command. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `numpy` and +/// `pep257` conventions, and disabled when using the `google` conventions. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """Returns the mean of the given values.""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct NonImperativeMood { first_line: String, diff --git a/crates/ruff/src/rules/pydocstyle/rules/not_empty.rs b/crates/ruff/src/rules/pydocstyle/rules/not_empty.rs index c349336e7c..3c89974b37 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/not_empty.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/not_empty.rs @@ -5,6 +5,29 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::Rule; +/// ## What it does +/// Checks for empty docstrings. +/// +/// ## Why is this bad? +/// An empty docstring is indicative of incomplete documentation. It should either +/// be removed or replaced with a meaningful docstring. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct EmptyDocstring; diff --git a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs index 97364cbc44..cefee351cb 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/not_missing.rs @@ -304,6 +304,7 @@ impl Violation for UndocumentedPublicMethod { /// return distance / time /// except ZeroDivisionError as exc: /// raise FasterThanLightError from exc +/// ``` /// /// ## References /// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) diff --git a/crates/ruff/src/rules/pydocstyle/rules/one_liner.rs b/crates/ruff/src/rules/pydocstyle/rules/one_liner.rs index bec528b4ed..7a3ad6980b 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/one_liner.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/one_liner.rs @@ -7,6 +7,31 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::registry::AsRule; +/// ## What it does +/// Checks for single-line docstrings that are broken across multiple lines. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that docstrings that _can_ fit on one line should be +/// formatted on a single line, for consistency and readability. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """ +/// Return the mean of the given values. +/// """ +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct FitsOnOneLine; diff --git a/crates/ruff/src/rules/pydocstyle/rules/sections.rs b/crates/ruff/src/rules/pydocstyle/rules/sections.rs index 5f7be37f5b..eb2676b1c9 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/sections.rs @@ -23,6 +23,68 @@ use crate::docstrings::Docstring; use crate::registry::{AsRule, Rule}; use crate::rules::pydocstyle::settings::Convention; +/// ## What it does +/// Checks for over-indented sections in docstrings. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Each section should use consistent indentation, with the section headers +/// matching the indentation of the docstring's opening quotes, and the +/// section bodies being indented one level further. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct SectionNotOverIndented { name: String, @@ -41,6 +103,86 @@ impl AlwaysAutofixableViolation for SectionNotOverIndented { } } +/// ## What it does +/// Checks for over-indented section underlines in docstrings. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Some docstring formats (like reStructuredText) use underlines to separate +/// section bodies from section headers. +/// +/// Avoid over-indenting the section underlines, as this can cause syntax +/// errors in reStructuredText. +/// +/// By default, this rule is enabled when using the `numpy` convention, and +/// disabled when using the `google` or `pep257` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct SectionUnderlineNotOverIndented { name: String, @@ -59,6 +201,67 @@ impl AlwaysAutofixableViolation for SectionUnderlineNotOverIndented { } } +/// ## What it does +/// Checks for section headers in docstrings that do not begin with capital +/// letters. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Section headers should be capitalized, for consistency. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// returns: +/// Speed as distance divided by time. +/// +/// raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct CapitalizeSectionName { name: String, @@ -77,6 +280,84 @@ impl AlwaysAutofixableViolation for CapitalizeSectionName { } } +/// ## What it does +/// Checks that section headers in docstrings that are not followed by a +/// newline. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Section headers should be followed by a newline, and not by another +/// character (like a colon), for consistency. +/// +/// This rule is enabled when using the `numpy` convention, and disabled +/// when using the `google` or `pep257` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters: +/// ----------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns: +/// -------- +/// float +/// Speed as distance divided by time. +/// +/// Raises: +/// ------- +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct NewLineAfterSectionName { name: String, @@ -95,6 +376,84 @@ impl AlwaysAutofixableViolation for NewLineAfterSectionName { } } +/// ## What it does +/// Checks for section headers in docstrings that are not followed by +/// underlines. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Some docstring formats (like reStructuredText) use underlines to separate +/// section bodies from section headers. +/// +/// This rule is enabled when using the `numpy` convention, and disabled +/// when using the `google` or `pep257` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct DashedUnderlineAfterSection { name: String, @@ -113,6 +472,90 @@ impl AlwaysAutofixableViolation for DashedUnderlineAfterSection { } } +/// ## What it does +/// Checks for section underlines in docstrings that are not on the line +/// immediately following the section name. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Some docstring formats (like reStructuredText) use underlines to separate +/// section bodies from section headers. +/// +/// When present, section underlines should be positioned on the line +/// immediately following the section header. +/// +/// This rule is enabled when using the `numpy` convention, and disabled +/// when using the `google` or `pep257` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct SectionUnderlineAfterName { name: String, @@ -131,6 +574,87 @@ impl AlwaysAutofixableViolation for SectionUnderlineAfterName { } } +/// ## What it does +/// Checks for section underlines in docstrings that do not match the length of +/// the corresponding section header. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Some docstring formats (like reStructuredText) use underlines to separate +/// section bodies from section headers. +/// +/// When present, section underlines should match the length of the +/// corresponding section header. +/// +/// This rule is enabled when using the `numpy` convention, and disabled +/// when using the `google` or `pep257` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// --- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// --- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// --- +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct SectionUnderlineMatchesSectionLength { name: String, @@ -149,6 +673,83 @@ impl AlwaysAutofixableViolation for SectionUnderlineMatchesSectionLength { } } +/// ## What it does +/// Checks for docstring sections that are not separated by a single blank +/// line. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Docstring sections should be separated by a blank line, for consistency and +/// compatibility with documentation tooling. +/// +/// This rule is enabled when using the `numpy` and `google` conventions, and +/// disabled when using the `pep257` convention. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct NoBlankLineAfterSection { name: String, @@ -167,6 +768,81 @@ impl AlwaysAutofixableViolation for NoBlankLineAfterSection { } } +/// ## What it does +/// Checks for docstring sections that are separated by a blank line. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Docstring sections should be separated by a blank line, for consistency and +/// compatibility with documentation tooling. +/// +/// This rule is enabled when using the `numpy` and `google` conventions, and +/// disabled when using the `pep257` convention. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct NoBlankLineBeforeSection { name: String, @@ -185,6 +861,81 @@ impl AlwaysAutofixableViolation for NoBlankLineBeforeSection { } } +/// ## What it does +/// Checks for missing blank lines after the last section of a multi-line +/// docstring. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// The last section in a docstring should be separated by a blank line, for +/// consistency and compatibility with documentation tooling. +/// +/// This rule is enabled when using the `numpy` convention, and disabled when +/// using the `pep257` and `google` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light.""" +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) #[violation] pub struct BlankLineAfterLastSection { name: String, @@ -203,6 +954,79 @@ impl AlwaysAutofixableViolation for BlankLineAfterLastSection { } } +/// ## What it does +/// Checks for docstrings that contain empty sections. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Empty docstring sections are indicative of missing documentation. Empty +/// sections should either be removed or filled in with relevant documentation. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Parameters +/// ---------- +/// distance : float +/// Distance traveled. +/// time : float +/// Time spent traveling. +/// +/// Returns +/// ------- +/// float +/// Speed as distance divided by time. +/// +/// Raises +/// ------ +/// FasterThanLightError +/// If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct EmptyDocstringSection { name: String, @@ -216,6 +1040,69 @@ impl Violation for EmptyDocstringSection { } } +/// ## What it does +/// Checks for docstring section headers that do not end with a colon. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// In a docstring, each section header should end with a colon, for +/// consistency. +/// +/// This rule is enabled when using the `google` convention, and disabled when +/// using the `pep257` and `numpy` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns +/// Speed as distance divided by time. +/// +/// Raises +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [Google Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct SectionNameEndsInColon { name: String, @@ -234,6 +1121,70 @@ impl AlwaysAutofixableViolation for SectionNameEndsInColon { } } +/// ## What it does +/// Checks for function docstrings that do not include documentation for all +/// parameters in the function. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Function docstrings often include a section for function arguments, which +/// should include documentation for every argument. Undocumented arguments are +/// indicative of missing documentation. +/// +/// This rule is enabled when using the `google` convention, and disabled when +/// using the `pep257` and `numpy` conventions. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct UndocumentedParam { pub names: Vec, @@ -253,6 +1204,69 @@ impl Violation for UndocumentedParam { } } +/// ## What it does +/// Checks for docstring sections that contain blank lines between the section +/// header and the section body. +/// +/// ## Why is this bad? +/// Multi-line docstrings are typically composed of a summary line, followed by +/// a blank line, followed by a series of sections, each with a section header +/// and a section body. +/// +/// Docstring sections should not contain blank lines between the section header +/// and the section body, for consistency. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent traveling. +/// +/// Returns: +/// Speed as distance divided by time. +/// +/// Raises: +/// FasterThanLightError: If speed is greater than the speed of light. +/// """ +/// try: +/// return distance / time +/// except ZeroDivisionError as exc: +/// raise FasterThanLightError from exc +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) +/// - [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html) +/// - [Google Python Style Guide - Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) #[violation] pub struct BlankLinesBetweenHeaderAndContent { name: String, diff --git a/crates/ruff/src/rules/pydocstyle/rules/starts_with_this.rs b/crates/ruff/src/rules/pydocstyle/rules/starts_with_this.rs index efe015b802..eccabe28ec 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/starts_with_this.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/starts_with_this.rs @@ -5,6 +5,39 @@ use crate::checkers::ast::Checker; use crate::docstrings::Docstring; use crate::rules::pydocstyle::helpers::normalize_word; +/// ## What it does +/// Checks for docstrings that start with `This`. +/// +/// ## Why is this bad? +/// [PEP 257] recommends that the first line of a docstring be written in the +/// imperative mood, for consistency. +/// +/// Hint: to rewrite the docstring in the imperative, phrase the first line as +/// if it were a command. +/// +/// This rule may not apply to all projects; its applicability is a matter of +/// convention. By default, this rule is enabled when using the `numpy` +/// convention,, and disabled when using the `google` and `pep257` conventions. +/// +/// ## Example +/// ```python +/// def average(values: list[float]) -> float: +/// """This function returns the mean of the given values.""" +/// ``` +/// +/// Use instead: +/// ```python +/// def average(values: list[float]) -> float: +/// """Return the mean of the given values.""" +/// ``` +/// +/// ## Options +/// - `pydocstyle.convention` +/// +/// ## References +/// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) +/// +/// [PEP 257]: https://peps.python.org/pep-0257/ #[violation] pub struct DocstringStartsWithThis; diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index 0c2680460c..be2ef93a46 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -33,6 +33,7 @@ KNOWN_FORMATTING_VIOLATIONS = [ "bad-quotes-inline-string", "bad-quotes-multiline-string", "explicit-string-concatenation", + "indent-with-spaces", "indentation-with-invalid-multiple", "line-too-long", "missing-trailing-comma", @@ -44,15 +45,20 @@ KNOWN_FORMATTING_VIOLATIONS = [ "multiple-spaces-before-operator", "multiple-statements-on-one-line-colon", "multiple-statements-on-one-line-semicolon", + "no-blank-line-before-function", "no-indented-block-comment", "no-space-after-block-comment", "no-space-after-inline-comment", + "one-blank-line-after-class", + "over-indentation", "over-indented", "prohibited-trailing-comma", "shebang-leading-whitespace", + "surrounding-whitespace", "too-few-spaces-before-inline-comment", "trailing-comma-on-bare-tuple", "triple-single-quotes", + "under-indentation", "unexpected-indentation-comment", "unicode-kind-prefix", "unnecessary-class-parentheses",