Use section name range for all section-related docstring diagnostics (#10740)

## Summary

We may not have had access to this in the past, but in short, if the
diagnostic is related to a specific section of a docstring, it seems
better to highlight the section (via the header) than the _entire_
docstring.

This should be completely compatible with existing `# noqa` since it's
always inside of a multi-line string anyway, and in such cases the `#
noqa` is always placed at the end of the multiline string.

Closes https://github.com/astral-sh/ruff/issues/10736.
This commit is contained in:
Charlie Marsh 2024-04-02 22:10:04 -04:00 committed by GitHub
parent 814b26f82e
commit e54b591ec7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 545 additions and 995 deletions

View file

@ -2,6 +2,7 @@ use itertools::Itertools;
use once_cell::sync::Lazy;
use regex::Regex;
use rustc_hash::FxHashSet;
use std::ops::Add;
use ruff_diagnostics::{AlwaysFixableViolation, Violation};
use ruff_diagnostics::{Diagnostic, Edit, Fix};
@ -10,8 +11,8 @@ use ruff_python_ast::docstrings::{clean_space, leading_space};
use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::ParameterWithDefault;
use ruff_python_semantic::analyze::visibility::is_staticmethod;
use ruff_python_trivia::{textwrap::dedent, PythonWhitespace};
use ruff_source_file::NewlineWithTrailingNewline;
use ruff_python_trivia::{textwrap::dedent, Cursor};
use ruff_source_file::{Line, NewlineWithTrailingNewline};
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::checkers::ast::Checker;
@ -1377,50 +1378,41 @@ fn blanks_and_section_underline(
}
if let Some(non_blank_line) = following_lines.next() {
let dash_line_found = is_dashed_underline(&non_blank_line);
if dash_line_found {
if let Some(dashed_line) = find_underline(&non_blank_line, '-') {
if blank_lines_after_header > 0 {
if checker.enabled(Rule::SectionUnderlineAfterName) {
let mut diagnostic = Diagnostic::new(
SectionUnderlineAfterName {
name: context.section_name().to_string(),
},
docstring.range(),
dashed_line,
);
let range = TextRange::new(context.following_range().start(), blank_lines_end);
// Delete any blank lines between the header and the underline.
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range)));
diagnostic.set_fix(Fix::safe_edit(Edit::deletion(
context.following_range().start(),
blank_lines_end,
)));
checker.diagnostics.push(diagnostic);
}
}
if non_blank_line
.trim()
.chars()
.filter(|char| *char == '-')
.count()
!= context.section_name().len()
{
if dashed_line.len().to_usize() != context.section_name().len() {
if checker.enabled(Rule::SectionUnderlineMatchesSectionLength) {
let mut diagnostic = Diagnostic::new(
SectionUnderlineMatchesSectionLength {
name: context.section_name().to_string(),
},
docstring.range(),
dashed_line,
);
// Replace the existing underline with a line of the appropriate length.
let content = format!(
"{}{}{}",
clean_space(docstring.indentation),
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
"-".repeat(context.section_name().len()),
checker.stylist().line_ending().as_str()
);
diagnostic.set_fix(Fix::safe_edit(Edit::replacement(
content,
blank_lines_end,
non_blank_line.full_end(),
dashed_line,
)));
checker.diagnostics.push(diagnostic);
}
}
@ -1432,8 +1424,9 @@ fn blanks_and_section_underline(
SectionUnderlineNotOverIndented {
name: context.section_name().to_string(),
},
docstring.range(),
dashed_line,
);
// Replace the existing indentation with whitespace of the appropriate length.
let range = TextRange::at(
blank_lines_end,
@ -1445,6 +1438,7 @@ fn blanks_and_section_underline(
} else {
Edit::range_replacement(contents, range)
}));
checker.diagnostics.push(diagnostic);
}
}
@ -1467,7 +1461,7 @@ fn blanks_and_section_underline(
EmptyDocstringSection {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
));
}
} else if checker.enabled(Rule::BlankLinesBetweenHeaderAndContent) {
@ -1475,7 +1469,7 @@ fn blanks_and_section_underline(
BlankLinesBetweenHeaderAndContent {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
);
// Delete any blank lines between the header and content.
diagnostic.set_fix(Fix::safe_edit(Edit::deletion(
@ -1491,22 +1485,36 @@ fn blanks_and_section_underline(
EmptyDocstringSection {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
));
}
}
} else {
let equal_line_found = non_blank_line
.chars()
.all(|char| char.is_whitespace() || char == '=');
if checker.enabled(Rule::DashedUnderlineAfterSection) {
if let Some(equal_line) = find_underline(&non_blank_line, '=') {
let mut diagnostic = Diagnostic::new(
DashedUnderlineAfterSection {
name: context.section_name().to_string(),
},
docstring.range(),
equal_line,
);
// If an existing underline is an equal sign line of the appropriate length,
// replace it with a dashed line.
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
"-".repeat(context.section_name().len()),
equal_line,
)));
checker.diagnostics.push(diagnostic);
} else {
let mut diagnostic = Diagnostic::new(
DashedUnderlineAfterSection {
name: context.section_name().to_string(),
},
context.section_name_range(),
);
// Add a dashed line (of the appropriate length) under the section header.
let content = format!(
"{}{}{}",
@ -1514,32 +1522,21 @@ fn blanks_and_section_underline(
clean_space(docstring.indentation),
"-".repeat(context.section_name().len()),
);
if equal_line_found
&& non_blank_line.trim_whitespace().len() == context.section_name().len()
{
// If an existing underline is an equal sign line of the appropriate length,
// replace it with a dashed line.
diagnostic.set_fix(Fix::safe_edit(Edit::replacement(
content,
context.summary_range().end(),
non_blank_line.end(),
)));
} else {
// Otherwise, insert a dashed line after the section header.
diagnostic.set_fix(Fix::safe_edit(Edit::insertion(
content,
context.summary_range().end(),
)));
}
checker.diagnostics.push(diagnostic);
}
}
if blank_lines_after_header > 0 {
if checker.enabled(Rule::BlankLinesBetweenHeaderAndContent) {
let mut diagnostic = Diagnostic::new(
BlankLinesBetweenHeaderAndContent {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
);
let range = TextRange::new(context.following_range().start(), blank_lines_end);
// Delete any blank lines between the header and content.
@ -1548,16 +1545,16 @@ fn blanks_and_section_underline(
}
}
}
}
} else {
// Nothing but blank lines after the section header.
else {
if checker.enabled(Rule::DashedUnderlineAfterSection) {
let mut diagnostic = Diagnostic::new(
DashedUnderlineAfterSection {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
);
// Add a dashed line (of the appropriate length) under the section header.
let content = format!(
"{}{}{}",
@ -1565,11 +1562,11 @@ fn blanks_and_section_underline(
clean_space(docstring.indentation),
"-".repeat(context.section_name().len()),
);
diagnostic.set_fix(Fix::safe_edit(Edit::insertion(
content,
context.summary_range().end(),
)));
checker.diagnostics.push(diagnostic);
}
if checker.enabled(Rule::EmptyDocstringSection) {
@ -1577,7 +1574,7 @@ fn blanks_and_section_underline(
EmptyDocstringSection {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
));
}
}
@ -1592,15 +1589,15 @@ fn common_section(
if checker.enabled(Rule::CapitalizeSectionName) {
let capitalized_section_name = context.kind().as_str();
if context.section_name() != capitalized_section_name {
let section_range = context.section_name_range();
let mut diagnostic = Diagnostic::new(
CapitalizeSectionName {
name: context.section_name().to_string(),
},
docstring.range(),
section_range,
);
// Replace the section title with the capitalized variant. This requires
// locating the start and end of the section name.
let section_range = context.section_name_range();
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
capitalized_section_name.to_string(),
section_range,
@ -1612,16 +1609,17 @@ fn common_section(
if checker.enabled(Rule::SectionNotOverIndented) {
let leading_space = leading_space(context.summary_line());
if leading_space.len() > docstring.indentation.len() {
let section_range = context.section_name_range();
let mut diagnostic = Diagnostic::new(
SectionNotOverIndented {
name: context.section_name().to_string(),
},
docstring.range(),
section_range,
);
// Replace the existing indentation with whitespace of the appropriate length.
let content = clean_space(docstring.indentation);
let fix_range = TextRange::at(context.start(), leading_space.text_len());
diagnostic.set_fix(Fix::safe_edit(if content.is_empty() {
Edit::range_deletion(fix_range)
} else {
@ -1641,11 +1639,12 @@ fn common_section(
.take_while(|line| line.trim().is_empty())
.count();
if num_blank_lines < 2 {
let section_range = context.section_name_range();
let mut diagnostic = Diagnostic::new(
NoBlankLineAfterSection {
name: context.section_name().to_string(),
},
docstring.range(),
section_range,
);
// Add a newline at the beginning of the next section.
diagnostic.set_fix(Fix::safe_edit(Edit::insertion(
@ -1682,11 +1681,12 @@ fn common_section(
context.end(),
);
let section_range = context.section_name_range();
let mut diagnostic = Diagnostic::new(
BlankLineAfterLastSection {
name: context.section_name().to_string(),
},
docstring.range(),
section_range,
);
diagnostic.set_fix(Fix::safe_edit(edit));
checker.diagnostics.push(diagnostic);
@ -1699,11 +1699,12 @@ fn common_section(
.previous_line()
.is_some_and(|line| line.trim().is_empty())
{
let section_range = context.section_name_range();
let mut diagnostic = Diagnostic::new(
NoBlankLineBeforeSection {
name: context.section_name().to_string(),
},
docstring.range(),
section_range,
);
// Add a blank line before the section.
diagnostic.set_fix(Fix::safe_edit(Edit::insertion(
@ -1800,10 +1801,11 @@ fn args_section(context: &SectionContext) -> FxHashSet<String> {
let leading_space = leading_space(first_line.as_str());
let relevant_lines = std::iter::once(first_line)
.chain(following_lines)
.map(|l| l.as_str())
.filter(|line| {
line.is_empty() || (line.starts_with(leading_space) && !is_dashed_underline(line))
line.is_empty()
|| (line.starts_with(leading_space) && find_underline(line, '-').is_none())
})
.map(|line| line.as_str())
.join("\n");
let args_content = dedent(&relevant_lines);
@ -1897,7 +1899,7 @@ fn numpy_section(
NewLineAfterSectionName {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
);
let section_range = context.section_name_range();
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(TextRange::at(
@ -1931,7 +1933,7 @@ fn google_section(
SectionNameEndsInColon {
name: context.section_name().to_string(),
},
docstring.range(),
context.section_name_range(),
);
// Replace the suffix.
let section_name_range = context.section_name_range();
@ -1991,7 +1993,35 @@ fn parse_google_sections(
}
}
fn is_dashed_underline(line: &str) -> bool {
let trimmed_line = line.trim();
!trimmed_line.is_empty() && trimmed_line.chars().all(|char| char == '-')
/// Returns the [`TextRange`] of the underline, if a line consists of only dashes.
fn find_underline(line: &Line, dash: char) -> Option<TextRange> {
let mut cursor = Cursor::new(line.as_str());
// Eat leading whitespace.
cursor.eat_while(char::is_whitespace);
// Determine the start of the dashes.
let offset = cursor.token_len();
// Consume the dashes.
cursor.start_token();
cursor.eat_while(|c| c == dash);
// Determine the end of the dashes.
let len = cursor.token_len();
// If there are no dashes, return None.
if len == TextSize::new(0) {
return None;
}
// Eat trailing whitespace.
cursor.eat_while(char::is_whitespace);
// If there are any characters after the dashes, return None.
if !cursor.is_eof() {
return None;
}
Some(TextRange::at(offset, len).add(line.start()))
}

View file

@ -1,21 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
D214_module.py:1:1: D214 [*] Section is over-indented ("Returns")
D214_module.py:3:5: D214 [*] Section is over-indented ("Returns")
|
1 | / """A module docstring with D214 violations
2 | |
3 | | Returns
4 | | -----
5 | | valid returns
6 | |
7 | | Args
8 | | -----
9 | | valid args
10 | | """
| |___^ D214
11 |
12 | import os
1 | """A module docstring with D214 violations
2 |
3 | Returns
| ^^^^^^^ D214
4 | -----
5 | valid returns
|
= help: Remove over-indentation from "Returns"
@ -28,21 +21,14 @@ D214_module.py:1:1: D214 [*] Section is over-indented ("Returns")
5 5 | valid returns
6 6 |
D214_module.py:1:1: D214 [*] Section is over-indented ("Args")
D214_module.py:7:5: D214 [*] Section is over-indented ("Args")
|
1 | / """A module docstring with D214 violations
2 | |
3 | | Returns
4 | | -----
5 | | valid returns
6 | |
7 | | Args
8 | | -----
9 | | valid args
10 | | """
| |___^ D214
11 |
12 | import os
5 | valid returns
6 |
7 | Args
| ^^^^ D214
8 | -----
9 | valid args
|
= help: Remove over-indentation from "Args"
@ -55,5 +41,3 @@ D214_module.py:1:1: D214 [*] Section is over-indented ("Args")
8 8 | -----
9 9 | valid args
10 10 | """

View file

@ -1,19 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:144:5: D214 [*] Section is over-indented ("Returns")
sections.py:146:9: D214 [*] Section is over-indented ("Returns")
|
142 | @expect("D214: Section is over-indented ('Returns')")
143 | def section_overindented(): # noqa: D416
144 | """Toggle the gizmo.
| _____^
145 | |
146 | | Returns
147 | | -------
148 | | A value of some sort.
149 | |
150 | | """
| |_______^ D214
145 |
146 | Returns
| ^^^^^^^ D214
147 | -------
148 | A value of some sort.
|
= help: Remove over-indentation from "Returns"
@ -27,18 +22,13 @@ sections.py:144:5: D214 [*] Section is over-indented ("Returns")
148 148 | A value of some sort.
149 149 |
sections.py:558:5: D214 [*] Section is over-indented ("Returns")
sections.py:563:9: D214 [*] Section is over-indented ("Returns")
|
557 | def titlecase_sub_section_header():
558 | """Below, `Returns:` should be considered a section header.
| _____^
559 | |
560 | | Args:
561 | | Here's a note.
562 | |
563 | | Returns:
564 | | """
| |_______^ D214
561 | Here's a note.
562 |
563 | Returns:
| ^^^^^^^ D214
564 | """
|
= help: Remove over-indentation from "Returns"
@ -51,5 +41,3 @@ sections.py:558:5: D214 [*] Section is over-indented ("Returns")
564 564 | """
565 565 |
566 566 |

View file

@ -1,13 +1,13 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
D215.py:1:1: D215 [*] Section underline is over-indented ("TODO")
D215.py:3:5: D215 [*] Section underline is over-indented ("TODO")
|
1 | / """
2 | | TODO:
3 | | -
4 | | """
| |___^ D215
1 | """
2 | TODO:
3 | -
| ^ D215
4 | """
|
= help: Remove over-indentation from "TODO" underline
@ -17,5 +17,3 @@ D215.py:1:1: D215 [*] Section underline is over-indented ("TODO")
3 |- -
3 |+
4 4 | """

View file

@ -1,19 +1,12 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:156:5: D215 [*] Section underline is over-indented ("Returns")
sections.py:159:9: D215 [*] Section underline is over-indented ("Returns")
|
154 | @expect("D215: Section underline is over-indented (in section 'Returns')")
155 | def section_underline_overindented(): # noqa: D416
156 | """Toggle the gizmo.
| _____^
157 | |
158 | | Returns
159 | | -------
160 | | A value of some sort.
161 | |
162 | | """
| |_______^ D215
158 | Returns
159 | -------
| ^^^^^^^ D215
160 | A value of some sort.
|
= help: Remove over-indentation from "Returns" underline
@ -27,17 +20,12 @@ sections.py:156:5: D215 [*] Section underline is over-indented ("Returns")
161 161 |
162 162 | """
sections.py:170:5: D215 [*] Section underline is over-indented ("Returns")
sections.py:173:9: D215 [*] Section underline is over-indented ("Returns")
|
168 | @expect("D414: Section has no content ('Returns')")
169 | def section_underline_overindented_and_contentless(): # noqa: D416
170 | """Toggle the gizmo.
| _____^
171 | |
172 | | Returns
173 | | -------
174 | | """
| |_______^ D215
172 | Returns
173 | -------
| ^^^^^^^ D215
174 | """
|
= help: Remove over-indentation from "Returns" underline
@ -50,5 +38,3 @@ sections.py:170:5: D215 [*] Section underline is over-indented ("Returns")
174 174 | """
175 175 |
176 176 |

View file

@ -1,19 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:17:5: D405 [*] Section name should be properly capitalized ("returns")
sections.py:19:5: D405 [*] Section name should be properly capitalized ("returns")
|
15 | "('Returns', not 'returns')")
16 | def not_capitalized(): # noqa: D416
17 | """Toggle the gizmo.
| _____^
18 | |
19 | | returns
20 | | -------
21 | | A value of some sort.
22 | |
23 | | """
| |_______^ D405
18 |
19 | returns
| ^^^^^^^ D405
20 | -------
21 | A value of some sort.
|
= help: Capitalize "returns"
@ -27,27 +22,13 @@ sections.py:17:5: D405 [*] Section name should be properly capitalized ("returns
21 21 | A value of some sort.
22 22 |
sections.py:216:5: D405 [*] Section name should be properly capitalized ("Short summary")
sections.py:218:5: D405 [*] Section name should be properly capitalized ("Short summary")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D405
217 |
218 | Short summary
| ^^^^^^^^^^^^^ D405
219 | -------------
|
= help: Capitalize "Short summary"
@ -60,5 +41,3 @@ sections.py:216:5: D405 [*] Section name should be properly capitalized ("Short
219 219 | -------------
220 220 |
221 221 | This is the function's description, which will also specify what it

View file

@ -1,19 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:30:5: D406 [*] Section name should end with a newline ("Returns")
sections.py:32:5: D406 [*] Section name should end with a newline ("Returns")
|
28 | "('Returns', not 'Returns:')")
29 | def superfluous_suffix(): # noqa: D416
30 | """Toggle the gizmo.
| _____^
31 | |
32 | | Returns:
33 | | -------
34 | | A value of some sort.
35 | |
36 | | """
| |_______^ D406
31 |
32 | Returns:
| ^^^^^^^ D406
33 | -------
34 | A value of some sort.
|
= help: Add newline after "Returns"
@ -27,27 +22,13 @@ sections.py:30:5: D406 [*] Section name should end with a newline ("Returns")
34 34 | A value of some sort.
35 35 |
sections.py:216:5: D406 [*] Section name should end with a newline ("Raises")
sections.py:227:5: D406 [*] Section name should end with a newline ("Raises")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D406
225 | ------
226 | Many many wonderful things.
227 | Raises:
| ^^^^^^ D406
228 | My attention.
|
= help: Add newline after "Raises"
@ -61,20 +42,14 @@ sections.py:216:5: D406 [*] Section name should end with a newline ("Raises")
229 229 |
230 230 | """
sections.py:588:5: D406 [*] Section name should end with a newline ("Parameters")
sections.py:590:5: D406 [*] Section name should end with a newline ("Parameters")
|
587 | def test_lowercase_sub_section_header_should_be_valid(parameters: list[str], value: int): # noqa: D213
588 | """Test that lower case subsection header is valid even if it has the same name as section kind.
| _____^
589 | |
590 | | Parameters:
591 | | ----------
592 | | parameters:
593 | | A list of string parameters
594 | | value:
595 | | Some value
596 | | """
| |_______^ D406
589 |
590 | Parameters:
| ^^^^^^^^^^ D406
591 | ----------
592 | parameters:
|
= help: Add newline after "Parameters"
@ -87,5 +62,3 @@ sections.py:588:5: D406 [*] Section name should end with a newline ("Parameters"
591 591 | ----------
592 592 | parameters:
593 593 | A list of string parameters

View file

@ -1,18 +1,13 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:42:5: D407 [*] Missing dashed underline after section ("Returns")
sections.py:44:5: D407 [*] Missing dashed underline after section ("Returns")
|
40 | @expect("D407: Missing dashed underline after section ('Returns')")
41 | def no_underline(): # noqa: D416
42 | """Toggle the gizmo.
| _____^
43 | |
44 | | Returns
45 | | A value of some sort.
46 | |
47 | | """
| |_______^ D407
43 |
44 | Returns
| ^^^^^^^ D407
45 | A value of some sort.
|
= help: Add dashed line under "Returns"
@ -25,17 +20,14 @@ sections.py:42:5: D407 [*] Missing dashed underline after section ("Returns")
46 47 |
47 48 | """
sections.py:54:5: D407 [*] Missing dashed underline after section ("Returns")
sections.py:56:5: D407 [*] Missing dashed underline after section ("Returns")
|
52 | @expect("D414: Section has no content ('Returns')")
53 | def no_underline_and_no_description(): # noqa: D416
54 | """Toggle the gizmo.
| _____^
55 | |
56 | | Returns
57 | |
58 | | """
| |_______^ D407
55 |
56 | Returns
| ^^^^^^^ D407
57 |
58 | """
|
= help: Add dashed line under "Returns"
@ -48,15 +40,12 @@ sections.py:54:5: D407 [*] Missing dashed underline after section ("Returns")
58 59 | """
59 60 |
sections.py:65:5: D407 [*] Missing dashed underline after section ("Returns")
sections.py:67:5: D407 [*] Missing dashed underline after section ("Returns")
|
63 | @expect("D414: Section has no content ('Returns')")
64 | def no_underline_and_no_newline(): # noqa: D416
65 | """Toggle the gizmo.
| _____^
66 | |
67 | | Returns"""
| |______________^ D407
66 |
67 | Returns"""
| ^^^^^^^ D407
|
= help: Add dashed line under "Returns"
@ -71,27 +60,13 @@ sections.py:65:5: D407 [*] Missing dashed underline after section ("Returns")
69 70 |
70 71 | @expect(_D213)
sections.py:216:5: D407 [*] Missing dashed underline after section ("Raises")
sections.py:227:5: D407 [*] Missing dashed underline after section ("Raises")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D407
225 | ------
226 | Many many wonderful things.
227 | Raises:
| ^^^^^^ D407
228 | My attention.
|
= help: Add dashed line under "Raises"
@ -104,23 +79,13 @@ sections.py:216:5: D407 [*] Missing dashed underline after section ("Raises")
229 230 |
230 231 | """
sections.py:261:5: D407 [*] Missing dashed underline after section ("Args")
sections.py:263:5: D407 [*] Missing dashed underline after section ("Args")
|
259 | @expect("D414: Section has no content ('Returns')")
260 | def valid_google_style_section(): # noqa: D406, D407
261 | """Toggle the gizmo.
| _____^
262 | |
263 | | Args:
264 | | note: A random string.
265 | |
266 | | Returns:
267 | |
268 | | Raises:
269 | | RandomError: A random error that occurs randomly.
270 | |
271 | | """
| |_______^ D407
262 |
263 | Args:
| ^^^^ D407
264 | note: A random string.
|
= help: Add dashed line under "Args"
@ -133,23 +98,14 @@ sections.py:261:5: D407 [*] Missing dashed underline after section ("Args")
265 266 |
266 267 | Returns:
sections.py:261:5: D407 [*] Missing dashed underline after section ("Returns")
sections.py:266:5: D407 [*] Missing dashed underline after section ("Returns")
|
259 | @expect("D414: Section has no content ('Returns')")
260 | def valid_google_style_section(): # noqa: D406, D407
261 | """Toggle the gizmo.
| _____^
262 | |
263 | | Args:
264 | | note: A random string.
265 | |
266 | | Returns:
267 | |
268 | | Raises:
269 | | RandomError: A random error that occurs randomly.
270 | |
271 | | """
| |_______^ D407
264 | note: A random string.
265 |
266 | Returns:
| ^^^^^^^ D407
267 |
268 | Raises:
|
= help: Add dashed line under "Returns"
@ -162,23 +118,13 @@ sections.py:261:5: D407 [*] Missing dashed underline after section ("Returns")
268 269 | Raises:
269 270 | RandomError: A random error that occurs randomly.
sections.py:261:5: D407 [*] Missing dashed underline after section ("Raises")
sections.py:268:5: D407 [*] Missing dashed underline after section ("Raises")
|
259 | @expect("D414: Section has no content ('Returns')")
260 | def valid_google_style_section(): # noqa: D406, D407
261 | """Toggle the gizmo.
| _____^
262 | |
263 | | Args:
264 | | note: A random string.
265 | |
266 | | Returns:
267 | |
268 | | Raises:
269 | | RandomError: A random error that occurs randomly.
270 | |
271 | | """
| |_______^ D407
266 | Returns:
267 |
268 | Raises:
| ^^^^^^ D407
269 | RandomError: A random error that occurs randomly.
|
= help: Add dashed line under "Raises"
@ -191,18 +137,13 @@ sections.py:261:5: D407 [*] Missing dashed underline after section ("Raises")
270 271 |
271 272 | """
sections.py:278:5: D407 [*] Missing dashed underline after section ("Args")
sections.py:280:5: D407 [*] Missing dashed underline after section ("Args")
|
276 | "('Args:', not 'Args')")
277 | def missing_colon_google_style_section(): # noqa: D406, D407
278 | """Toggle the gizmo.
| _____^
279 | |
280 | | Args
281 | | note: A random string.
282 | |
283 | | """
| |_______^ D407
279 |
280 | Args
| ^^^^ D407
281 | note: A random string.
|
= help: Add dashed line under "Args"
@ -215,21 +156,14 @@ sections.py:278:5: D407 [*] Missing dashed underline after section ("Args")
282 283 |
283 284 | """
sections.py:293:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:297:9: D407 [*] Missing dashed underline after section ("Args")
|
292 | def bar(y=2): # noqa: D207, D213, D406, D407
293 | """Nested function test for docstrings.
| _________^
294 | |
295 | | Will this work when referencing x?
296 | |
297 | | Args:
298 | | x: Test something
299 | | that is broken.
300 | |
301 | | """
| |___________^ D407
302 | print(x)
295 | Will this work when referencing x?
296 |
297 | Args:
| ^^^^ D407
298 | x: Test something
299 | that is broken.
|
= help: Add dashed line under "Args"
@ -242,18 +176,13 @@ sections.py:293:9: D407 [*] Missing dashed underline after section ("Args")
299 300 | that is broken.
300 301 |
sections.py:310:5: D407 [*] Missing dashed underline after section ("Args")
sections.py:312:5: D407 [*] Missing dashed underline after section ("Args")
|
308 | "'test_missing_google_args' docstring)")
309 | def test_missing_google_args(x=1, y=2, _private=3): # noqa: D406, D407
310 | """Toggle the gizmo.
| _____^
311 | |
312 | | Args:
313 | | x (int): The greatest integer.
314 | |
315 | | """
| |_______^ D407
311 |
312 | Args:
| ^^^^ D407
313 | x (int): The greatest integer.
|
= help: Add dashed line under "Args"
@ -266,20 +195,14 @@ sections.py:310:5: D407 [*] Missing dashed underline after section ("Args")
314 315 |
315 316 | """
sections.py:322:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:324:9: D407 [*] Missing dashed underline after section ("Args")
|
321 | def test_method(self, test, another_test, _): # noqa: D213, D407
322 | """Test a valid args section.
| _________^
323 | |
324 | | Args:
325 | | test: A parameter.
326 | | another_test: Another parameter.
327 | |
328 | | """
| |___________^ D407
329 |
330 | @expect("D417: Missing argument descriptions in the docstring "
323 |
324 | Args:
| ^^^^ D407
325 | test: A parameter.
326 | another_test: Another parameter.
|
= help: Add dashed line under "Args"
@ -292,20 +215,13 @@ sections.py:322:9: D407 [*] Missing dashed underline after section ("Args")
326 327 | another_test: Another parameter.
327 328 |
sections.py:334:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:336:9: D407 [*] Missing dashed underline after section ("Args")
|
332 | "'test_missing_args' docstring)", arg_count=5)
333 | def test_missing_args(self, test, x, y, z=3, _private_arg=3): # noqa: D213, D407
334 | """Test a valid args section.
| _________^
335 | |
336 | | Args:
337 | | x: Another parameter.
338 | |
339 | | """
| |___________^ D407
340 |
341 | @classmethod
335 |
336 | Args:
| ^^^^ D407
337 | x: Another parameter.
|
= help: Add dashed line under "Args"
@ -318,21 +234,14 @@ sections.py:334:9: D407 [*] Missing dashed underline after section ("Args")
338 339 |
339 340 | """
sections.py:346:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:348:9: D407 [*] Missing dashed underline after section ("Args")
|
344 | "'test_missing_args_class_method' docstring)", arg_count=5)
345 | def test_missing_args_class_method(cls, test, x, y, _, z=3): # noqa: D213, D407
346 | """Test a valid args section.
| _________^
347 | |
348 | | Args:
349 | | x: Another parameter. The parameter below is missing description.
350 | | y:
351 | |
352 | | """
| |___________^ D407
353 |
354 | @staticmethod
347 |
348 | Args:
| ^^^^ D407
349 | x: Another parameter. The parameter below is missing description.
350 | y:
|
= help: Add dashed line under "Args"
@ -345,20 +254,13 @@ sections.py:346:9: D407 [*] Missing dashed underline after section ("Args")
350 351 | y:
351 352 |
sections.py:359:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:361:9: D407 [*] Missing dashed underline after section ("Args")
|
357 | "'test_missing_args_static_method' docstring)", arg_count=4)
358 | def test_missing_args_static_method(a, x, y, _test, z=3): # noqa: D213, D407
359 | """Test a valid args section.
| _________^
360 | |
361 | | Args:
362 | | x: Another parameter.
363 | |
364 | | """
| |___________^ D407
365 |
366 | @staticmethod
360 |
361 | Args:
| ^^^^ D407
362 | x: Another parameter.
|
= help: Add dashed line under "Args"
@ -371,20 +273,13 @@ sections.py:359:9: D407 [*] Missing dashed underline after section ("Args")
363 364 |
364 365 | """
sections.py:371:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:373:9: D407 [*] Missing dashed underline after section ("Args")
|
369 | "'test_missing_docstring' docstring)", arg_count=2)
370 | def test_missing_docstring(a, b): # noqa: D213, D407
371 | """Test a valid args section.
| _________^
372 | |
373 | | Args:
374 | | a:
375 | |
376 | | """
| |___________^ D407
377 |
378 | @staticmethod
372 |
373 | Args:
| ^^^^ D407
374 | a:
|
= help: Add dashed line under "Args"
@ -397,24 +292,14 @@ sections.py:371:9: D407 [*] Missing dashed underline after section ("Args")
375 376 |
376 377 | """
sections.py:380:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:382:9: D407 [*] Missing dashed underline after section ("Args")
|
378 | @staticmethod
379 | def test_hanging_indent(skip, verbose): # noqa: D213, D407
380 | """Do stuff.
| _________^
381 | |
382 | | Args:
383 | | skip (:attr:`.Skip`):
384 | | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
385 | | Etiam at tellus a tellus faucibus maximus. Curabitur tellus
386 | | mauris, semper id vehicula ac, feugiat ut tortor.
387 | | verbose (bool):
388 | | If True, print out as much information as possible.
389 | | If False, print out concise "one-liner" information.
390 | |
391 | | """
| |___________^ D407
381 |
382 | Args:
| ^^^^ D407
383 | skip (:attr:`.Skip`):
384 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
= help: Add dashed line under "Args"
@ -427,20 +312,13 @@ sections.py:380:9: D407 [*] Missing dashed underline after section ("Args")
384 385 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
385 386 | Etiam at tellus a tellus faucibus maximus. Curabitur tellus
sections.py:499:9: D407 [*] Missing dashed underline after section ("Args")
sections.py:503:9: D407 [*] Missing dashed underline after section ("Args")
|
497 | "'test_incorrect_indent' docstring)", arg_count=3)
498 | def test_incorrect_indent(self, x=1, y=2): # noqa: D207, D213, D407
499 | """Reproducing issue #437.
| _________^
500 | |
501 | | Testing this incorrectly indented docstring.
502 | |
503 | | Args:
504 | | x: Test argument.
505 | |
506 | | """
| |___________^ D407
501 | Testing this incorrectly indented docstring.
502 |
503 | Args:
| ^^^^ D407
504 | x: Test argument.
|
= help: Add dashed line under "Args"
@ -453,16 +331,12 @@ sections.py:499:9: D407 [*] Missing dashed underline after section ("Args")
505 506 |
506 507 | """
sections.py:519:5: D407 [*] Missing dashed underline after section ("Parameters")
sections.py:522:5: D407 [*] Missing dashed underline after section ("Parameters")
|
518 | def replace_equals_with_dash():
519 | """Equal length equals should be replaced with dashes.
| _____^
520 | |
521 | | Parameters
522 | | ==========
523 | | """
| |_______^ D407
521 | Parameters
522 | ==========
| ^^^^^^^^^^ D407
523 | """
|
= help: Add dashed line under "Parameters"
@ -476,16 +350,12 @@ sections.py:519:5: D407 [*] Missing dashed underline after section ("Parameters"
524 524 |
525 525 |
sections.py:527:5: D407 [*] Missing dashed underline after section ("Parameters")
sections.py:530:5: D407 [*] Missing dashed underline after section ("Parameters")
|
526 | def replace_equals_with_dash2():
527 | """Here, the length of equals is not the same.
| _____^
528 | |
529 | | Parameters
530 | | ===========
531 | | """
| |_______^ D407
529 | Parameters
530 | ===========
| ^^^^^^^^^^^ D407
531 | """
|
= help: Add dashed line under "Parameters"
@ -493,23 +363,19 @@ sections.py:527:5: D407 [*] Missing dashed underline after section ("Parameters"
527 527 | """Here, the length of equals is not the same.
528 528 |
529 529 | Parameters
530 |- ===========
530 |+ ----------
530 531 | ===========
531 532 | """
532 533 |
531 531 | """
532 532 |
533 533 |
sections.py:548:5: D407 [*] Missing dashed underline after section ("Args")
sections.py:550:5: D407 [*] Missing dashed underline after section ("Args")
|
547 | def lowercase_sub_section_header():
548 | """Below, `returns:` should _not_ be considered a section header.
| _____^
549 | |
550 | | Args:
551 | | Here's a note.
552 | |
553 | | returns:
554 | | """
| |_______^ D407
549 |
550 | Args:
| ^^^^ D407
551 | Here's a note.
|
= help: Add dashed line under "Args"
@ -522,18 +388,13 @@ sections.py:548:5: D407 [*] Missing dashed underline after section ("Args")
552 553 |
553 554 | returns:
sections.py:558:5: D407 [*] Missing dashed underline after section ("Args")
sections.py:560:5: D407 [*] Missing dashed underline after section ("Args")
|
557 | def titlecase_sub_section_header():
558 | """Below, `Returns:` should be considered a section header.
| _____^
559 | |
560 | | Args:
561 | | Here's a note.
562 | |
563 | | Returns:
564 | | """
| |_______^ D407
559 |
560 | Args:
| ^^^^ D407
561 | Here's a note.
|
= help: Add dashed line under "Args"
@ -546,18 +407,13 @@ sections.py:558:5: D407 [*] Missing dashed underline after section ("Args")
562 563 |
563 564 | Returns:
sections.py:558:5: D407 [*] Missing dashed underline after section ("Returns")
sections.py:563:9: D407 [*] Missing dashed underline after section ("Returns")
|
557 | def titlecase_sub_section_header():
558 | """Below, `Returns:` should be considered a section header.
| _____^
559 | |
560 | | Args:
561 | | Here's a note.
562 | |
563 | | Returns:
564 | | """
| |_______^ D407
561 | Here's a note.
562 |
563 | Returns:
| ^^^^^^^ D407
564 | """
|
= help: Add dashed line under "Returns"
@ -570,19 +426,14 @@ sections.py:558:5: D407 [*] Missing dashed underline after section ("Returns")
565 566 |
566 567 |
sections.py:600:4: D407 [*] Missing dashed underline after section ("Parameters")
sections.py:602:4: D407 [*] Missing dashed underline after section ("Parameters")
|
599 | def test_lowercase_sub_section_header_different_kind(returns: int):
600 | """Test that lower case subsection header is valid even if it is of a different kind.
| ____^
601 | |
602 | | Parameters
603 | | ------------------
604 | | returns:
605 | | some value
606 | |
607 | | """
| |______^ D407
601 |
602 | Parameters
| ^^^^^^^^^^ D407
603 | ------------------
604 | returns:
|
= help: Add dashed line under "Parameters"
@ -594,5 +445,3 @@ sections.py:600:4: D407 [*] Missing dashed underline after section ("Parameters"
603 604 | ------------------
604 605 | returns:
605 606 | some value

View file

@ -1,20 +1,13 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:94:5: D408 [*] Section underline should be in the line following the section's name ("Returns")
sections.py:98:5: D408 [*] Section underline should be in the line following the section's name ("Returns")
|
92 | "section's name ('Returns')")
93 | def blank_line_before_underline(): # noqa: D416
94 | """Toggle the gizmo.
| _____^
95 | |
96 | | Returns
97 | |
98 | | -------
99 | | A value of some sort.
100 | |
101 | | """
| |_______^ D408
96 | Returns
97 |
98 | -------
| ^^^^^^^ D408
99 | A value of some sort.
|
= help: Add underline to "Returns"
@ -26,5 +19,3 @@ sections.py:94:5: D408 [*] Section underline should be in the line following the
98 97 | -------
99 98 | A value of some sort.
100 99 |

View file

@ -1,19 +1,12 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:108:5: D409 [*] Section underline should match the length of its name ("Returns")
sections.py:111:5: D409 [*] Section underline should match the length of its name ("Returns")
|
106 | "(Expected 7 dashes in section 'Returns', got 2)")
107 | def bad_underline_length(): # noqa: D416
108 | """Toggle the gizmo.
| _____^
109 | |
110 | | Returns
111 | | --
112 | | A value of some sort.
113 | |
114 | | """
| |_______^ D409
110 | Returns
111 | --
| ^^ D409
112 | A value of some sort.
|
= help: Adjust underline length to match "Returns"
@ -27,27 +20,13 @@ sections.py:108:5: D409 [*] Section underline should match the length of its nam
113 113 |
114 114 | """
sections.py:216:5: D409 [*] Section underline should match the length of its name ("Returns")
sections.py:225:5: D409 [*] Section underline should match the length of its name ("Returns")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D409
224 | Returns
225 | ------
| ^^^^^^ D409
226 | Many many wonderful things.
227 | Raises:
|
= help: Adjust underline length to match "Returns"
@ -61,28 +40,13 @@ sections.py:216:5: D409 [*] Section underline should match the length of its nam
227 227 | Raises:
228 228 | My attention.
sections.py:568:5: D409 [*] Section underline should match the length of its name ("Other Parameters")
sections.py:578:5: D409 [*] Section underline should match the length of its name ("Other Parameters")
|
567 | def test_method_should_be_correctly_capitalized(parameters: list[str], other_parameters: dict[str, str]): # noqa: D213
568 | """Test parameters and attributes sections are capitalized correctly.
| _____^
569 | |
570 | | Parameters
571 | | ----------
572 | | parameters:
573 | | A list of string parameters
574 | | other_parameters:
575 | | A dictionary of string attributes
576 | |
577 | | Other Parameters
578 | | ----------
579 | | other_parameters:
580 | | A dictionary of string attributes
581 | | parameters:
582 | | A list of string parameters
583 | |
584 | | """
| |_______^ D409
577 | Other Parameters
578 | ----------
| ^^^^^^^^^^ D409
579 | other_parameters:
580 | A dictionary of string attributes
|
= help: Adjust underline length to match "Other Parameters"
@ -95,5 +59,3 @@ sections.py:568:5: D409 [*] Section underline should match the length of its nam
579 579 | other_parameters:
580 580 | A dictionary of string attributes
581 581 | parameters:

View file

@ -1,25 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
D410.py:2:5: D410 [*] Missing blank line after section ("Parameters")
D410.py:4:5: D410 [*] Missing blank line after section ("Parameters")
|
1 | def f(a: int, b: int) -> int:
2 | """Showcase function.
| _____^
3 | |
4 | | Parameters
5 | | ----------
6 | | a : int
7 | | _description_
8 | | b : int
9 | | _description_
10 | | Returns
11 | | -------
12 | | int
13 | | _description
14 | | """
| |_______^ D410
15 | return b - a
2 | """Showcase function.
3 |
4 | Parameters
| ^^^^^^^^^^ D410
5 | ----------
6 | a : int
|
= help: Add blank line after "Parameters"
@ -32,18 +21,14 @@ D410.py:2:5: D410 [*] Missing blank line after section ("Parameters")
11 12 | -------
12 13 | int
D410.py:19:5: D410 [*] Missing blank line after section ("Parameters")
D410.py:21:5: D410 [*] Missing blank line after section ("Parameters")
|
18 | def f() -> int:
19 | """Showcase function.
| _____^
20 | |
21 | | Parameters
22 | | ----------
23 | | Returns
24 | | -------
25 | | """
| |_______^ D410
20 |
21 | Parameters
| ^^^^^^^^^^ D410
22 | ----------
23 | Returns
|
= help: Add blank line after "Parameters"
@ -55,5 +40,3 @@ D410.py:19:5: D410 [*] Missing blank line after section ("Parameters")
23 24 | Returns
24 25 | -------
25 26 | """

View file

@ -1,24 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:76:5: D410 [*] Missing blank line after section ("Returns")
sections.py:78:5: D410 [*] Missing blank line after section ("Returns")
|
74 | @expect("D414: Section has no content ('Yields')")
75 | def consecutive_sections(): # noqa: D416
76 | """Toggle the gizmo.
| _____^
77 | |
78 | | Returns
79 | | -------
80 | | Yields
81 | | ------
82 | |
83 | | Raises
84 | | ------
85 | | Questions.
86 | |
87 | | """
| |_______^ D410
77 |
78 | Returns
| ^^^^^^^ D410
79 | -------
80 | Yields
|
= help: Add blank line after "Returns"
@ -31,27 +21,14 @@ sections.py:76:5: D410 [*] Missing blank line after section ("Returns")
81 82 | ------
82 83 |
sections.py:216:5: D410 [*] Missing blank line after section ("Returns")
sections.py:224:5: D410 [*] Missing blank line after section ("Returns")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D410
222 | returns.
223 |
224 | Returns
| ^^^^^^^ D410
225 | ------
226 | Many many wonderful things.
|
= help: Add blank line after "Returns"
@ -63,5 +40,3 @@ sections.py:216:5: D410 [*] Missing blank line after section ("Returns")
227 228 | Raises:
228 229 | My attention.
229 230 |

View file

@ -1,24 +1,13 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:76:5: D411 [*] Missing blank line before section ("Yields")
sections.py:80:5: D411 [*] Missing blank line before section ("Yields")
|
74 | @expect("D414: Section has no content ('Yields')")
75 | def consecutive_sections(): # noqa: D416
76 | """Toggle the gizmo.
| _____^
77 | |
78 | | Returns
79 | | -------
80 | | Yields
81 | | ------
82 | |
83 | | Raises
84 | | ------
85 | | Questions.
86 | |
87 | | """
| |_______^ D411
78 | Returns
79 | -------
80 | Yields
| ^^^^^^ D411
81 | ------
|
= help: Add blank line before "Yields"
@ -31,20 +20,13 @@ sections.py:76:5: D411 [*] Missing blank line before section ("Yields")
81 82 | ------
82 83 |
sections.py:131:5: D411 [*] Missing blank line before section ("Returns")
sections.py:134:5: D411 [*] Missing blank line before section ("Returns")
|
129 | @expect("D411: Missing blank line before section ('Returns')")
130 | def no_blank_line_before_section(): # noqa: D416
131 | """Toggle the gizmo.
| _____^
132 | |
133 | | The function's description.
134 | | Returns
135 | | -------
136 | | A value of some sort.
137 | |
138 | | """
| |_______^ D411
133 | The function's description.
134 | Returns
| ^^^^^^^ D411
135 | -------
136 | A value of some sort.
|
= help: Add blank line before "Returns"
@ -57,27 +39,13 @@ sections.py:131:5: D411 [*] Missing blank line before section ("Returns")
135 136 | -------
136 137 | A value of some sort.
sections.py:216:5: D411 [*] Missing blank line before section ("Raises")
sections.py:227:5: D411 [*] Missing blank line before section ("Raises")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D411
225 | ------
226 | Many many wonderful things.
227 | Raises:
| ^^^^^^ D411
228 | My attention.
|
= help: Add blank line before "Raises"
@ -89,5 +57,3 @@ sections.py:216:5: D411 [*] Missing blank line before section ("Raises")
227 228 | Raises:
228 229 | My attention.
229 230 |

View file

@ -1,27 +1,13 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:216:5: D412 [*] No blank lines allowed between a section header and its content ("Short summary")
sections.py:218:5: D412 [*] No blank lines allowed between a section header and its content ("Short summary")
|
214 | @expect("D407: Missing dashed underline after section ('Raises')")
215 | def multiple_sections(): # noqa: D416
216 | """Toggle the gizmo.
| _____^
217 | |
218 | | Short summary
219 | | -------------
220 | |
221 | | This is the function's description, which will also specify what it
222 | | returns.
223 | |
224 | | Returns
225 | | ------
226 | | Many many wonderful things.
227 | | Raises:
228 | | My attention.
229 | |
230 | | """
| |_______^ D412
217 |
218 | Short summary
| ^^^^^^^^^^^^^ D412
219 | -------------
|
= help: Remove blank line(s)
@ -33,5 +19,3 @@ sections.py:216:5: D412 [*] No blank lines allowed between a section header and
221 220 | This is the function's description, which will also specify what it
222 221 | returns.
223 222 |

View file

@ -1,18 +1,14 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
D413.py:1:1: D413 [*] Missing blank line after last section ("Returns")
D413.py:7:1: D413 [*] Missing blank line after last section ("Returns")
|
1 | / """Do something.
2 | |
3 | | Args:
4 | | x: the value
5 | | with a hanging indent
6 | |
7 | | Returns:
8 | | the value
9 | | """
| |___^ D413
5 | with a hanging indent
6 |
7 | Returns:
| ^^^^^^^ D413
8 | the value
9 | """
|
= help: Add blank line after "Returns"
@ -25,20 +21,14 @@ D413.py:1:1: D413 [*] Missing blank line after last section ("Returns")
10 11 |
11 12 |
D413.py:13:5: D413 [*] Missing blank line after last section ("Returns")
D413.py:19:5: D413 [*] Missing blank line after last section ("Returns")
|
12 | def func():
13 | """Do something.
| _____^
14 | |
15 | | Args:
16 | | x: the value
17 | | with a hanging indent
18 | |
19 | | Returns:
20 | | the value
21 | | """
| |_______^ D413
17 | with a hanging indent
18 |
19 | Returns:
| ^^^^^^^ D413
20 | the value
21 | """
|
= help: Add blank line after "Returns"
@ -51,19 +41,13 @@ D413.py:13:5: D413 [*] Missing blank line after last section ("Returns")
22 23 |
23 24 |
D413.py:52:5: D413 [*] Missing blank line after last section ("Returns")
D413.py:58:5: D413 [*] Missing blank line after last section ("Returns")
|
51 | def func():
52 | """Do something.
| _____^
53 | |
54 | | Args:
55 | | x: the value
56 | | with a hanging indent
57 | |
58 | | Returns:
59 | | the value"""
| |____________________^ D413
56 | with a hanging indent
57 |
58 | Returns:
| ^^^^^^^ D413
59 | the value"""
|
= help: Add blank line after "Returns"
@ -79,20 +63,14 @@ D413.py:52:5: D413 [*] Missing blank line after last section ("Returns")
61 63 |
62 64 | def func():
D413.py:63:5: D413 [*] Missing blank line after last section ("Returns")
D413.py:69:5: D413 [*] Missing blank line after last section ("Returns")
|
62 | def func():
63 | """Do something.
| _____^
64 | |
65 | | Args:
66 | | x: the value
67 | | with a hanging indent
68 | |
69 | | Returns:
70 | | the value
71 | | """
| |___________^ D413
67 | with a hanging indent
68 |
69 | Returns:
| ^^^^^^^ D413
70 | the value
71 | """
|
= help: Add blank line after "Returns"

View file

@ -1,15 +1,12 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:65:5: D413 [*] Missing blank line after last section ("Returns")
sections.py:67:5: D413 [*] Missing blank line after last section ("Returns")
|
63 | @expect("D414: Section has no content ('Returns')")
64 | def no_underline_and_no_newline(): # noqa: D416
65 | """Toggle the gizmo.
| _____^
66 | |
67 | | Returns"""
| |______________^ D413
66 |
67 | Returns"""
| ^^^^^^^ D413
|
= help: Add blank line after "Returns"
@ -25,18 +22,14 @@ sections.py:65:5: D413 [*] Missing blank line after last section ("Returns")
69 71 |
70 72 | @expect(_D213)
sections.py:120:5: D413 [*] Missing blank line after last section ("Returns")
sections.py:122:5: D413 [*] Missing blank line after last section ("Returns")
|
118 | @expect("D413: Missing blank line after last section ('Returns')")
119 | def no_blank_line_after_last_section(): # noqa: D416
120 | """Toggle the gizmo.
| _____^
121 | |
122 | | Returns
123 | | -------
124 | | A value of some sort.
125 | | """
| |_______^ D413
121 |
122 | Returns
| ^^^^^^^ D413
123 | -------
124 | A value of some sort.
|
= help: Add blank line after "Returns"
@ -49,17 +42,14 @@ sections.py:120:5: D413 [*] Missing blank line after last section ("Returns")
126 127 |
127 128 |
sections.py:170:5: D413 [*] Missing blank line after last section ("Returns")
sections.py:172:5: D413 [*] Missing blank line after last section ("Returns")
|
168 | @expect("D414: Section has no content ('Returns')")
169 | def section_underline_overindented_and_contentless(): # noqa: D416
170 | """Toggle the gizmo.
| _____^
171 | |
172 | | Returns
173 | | -------
174 | | """
| |_______^ D413
171 |
172 | Returns
| ^^^^^^^ D413
173 | -------
174 | """
|
= help: Add blank line after "Returns"
@ -72,16 +62,14 @@ sections.py:170:5: D413 [*] Missing blank line after last section ("Returns")
175 176 |
176 177 |
sections.py:519:5: D413 [*] Missing blank line after last section ("Parameters")
sections.py:521:5: D413 [*] Missing blank line after last section ("Parameters")
|
518 | def replace_equals_with_dash():
519 | """Equal length equals should be replaced with dashes.
| _____^
520 | |
521 | | Parameters
522 | | ==========
523 | | """
| |_______^ D413
520 |
521 | Parameters
| ^^^^^^^^^^ D413
522 | ==========
523 | """
|
= help: Add blank line after "Parameters"
@ -94,16 +82,14 @@ sections.py:519:5: D413 [*] Missing blank line after last section ("Parameters")
524 525 |
525 526 |
sections.py:527:5: D413 [*] Missing blank line after last section ("Parameters")
sections.py:529:5: D413 [*] Missing blank line after last section ("Parameters")
|
526 | def replace_equals_with_dash2():
527 | """Here, the length of equals is not the same.
| _____^
528 | |
529 | | Parameters
530 | | ===========
531 | | """
| |_______^ D413
528 |
529 | Parameters
| ^^^^^^^^^^ D413
530 | ===========
531 | """
|
= help: Add blank line after "Parameters"
@ -116,18 +102,13 @@ sections.py:527:5: D413 [*] Missing blank line after last section ("Parameters")
532 533 |
533 534 |
sections.py:548:5: D413 [*] Missing blank line after last section ("Args")
sections.py:550:5: D413 [*] Missing blank line after last section ("Args")
|
547 | def lowercase_sub_section_header():
548 | """Below, `returns:` should _not_ be considered a section header.
| _____^
549 | |
550 | | Args:
551 | | Here's a note.
552 | |
553 | | returns:
554 | | """
| |_______^ D413
549 |
550 | Args:
| ^^^^ D413
551 | Here's a note.
|
= help: Add blank line after "Args"
@ -140,18 +121,13 @@ sections.py:548:5: D413 [*] Missing blank line after last section ("Args")
555 556 |
556 557 |
sections.py:558:5: D413 [*] Missing blank line after last section ("Returns")
sections.py:563:9: D413 [*] Missing blank line after last section ("Returns")
|
557 | def titlecase_sub_section_header():
558 | """Below, `Returns:` should be considered a section header.
| _____^
559 | |
560 | | Args:
561 | | Here's a note.
562 | |
563 | | Returns:
564 | | """
| |_______^ D413
561 | Here's a note.
562 |
563 | Returns:
| ^^^^^^^ D413
564 | """
|
= help: Add blank line after "Returns"
@ -164,20 +140,14 @@ sections.py:558:5: D413 [*] Missing blank line after last section ("Returns")
565 566 |
566 567 |
sections.py:588:5: D413 [*] Missing blank line after last section ("Parameters")
sections.py:590:5: D413 [*] Missing blank line after last section ("Parameters")
|
587 | def test_lowercase_sub_section_header_should_be_valid(parameters: list[str], value: int): # noqa: D213
588 | """Test that lower case subsection header is valid even if it has the same name as section kind.
| _____^
589 | |
590 | | Parameters:
591 | | ----------
592 | | parameters:
593 | | A list of string parameters
594 | | value:
595 | | Some value
596 | | """
| |_______^ D413
589 |
590 | Parameters:
| ^^^^^^^^^^ D413
591 | ----------
592 | parameters:
|
= help: Add blank line after "Parameters"

View file

@ -1,114 +1,68 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
sections.py:54:5: D414 Section has no content ("Returns")
sections.py:56:5: D414 Section has no content ("Returns")
|
52 | @expect("D414: Section has no content ('Returns')")
53 | def no_underline_and_no_description(): # noqa: D416
54 | """Toggle the gizmo.
| _____^
55 | |
56 | | Returns
57 | |
58 | | """
| |_______^ D414
55 |
56 | Returns
| ^^^^^^^ D414
57 |
58 | """
|
sections.py:65:5: D414 Section has no content ("Returns")
sections.py:67:5: D414 Section has no content ("Returns")
|
63 | @expect("D414: Section has no content ('Returns')")
64 | def no_underline_and_no_newline(): # noqa: D416
65 | """Toggle the gizmo.
| _____^
66 | |
67 | | Returns"""
| |______________^ D414
66 |
67 | Returns"""
| ^^^^^^^ D414
|
sections.py:76:5: D414 Section has no content ("Returns")
sections.py:78:5: D414 Section has no content ("Returns")
|
74 | @expect("D414: Section has no content ('Yields')")
75 | def consecutive_sections(): # noqa: D416
76 | """Toggle the gizmo.
| _____^
77 | |
78 | | Returns
79 | | -------
80 | | Yields
81 | | ------
82 | |
83 | | Raises
84 | | ------
85 | | Questions.
86 | |
87 | | """
| |_______^ D414
77 |
78 | Returns
| ^^^^^^^ D414
79 | -------
80 | Yields
|
sections.py:76:5: D414 Section has no content ("Yields")
sections.py:80:5: D414 Section has no content ("Yields")
|
74 | @expect("D414: Section has no content ('Yields')")
75 | def consecutive_sections(): # noqa: D416
76 | """Toggle the gizmo.
| _____^
77 | |
78 | | Returns
79 | | -------
80 | | Yields
81 | | ------
82 | |
83 | | Raises
84 | | ------
85 | | Questions.
86 | |
87 | | """
| |_______^ D414
78 | Returns
79 | -------
80 | Yields
| ^^^^^^ D414
81 | ------
|
sections.py:170:5: D414 Section has no content ("Returns")
sections.py:172:5: D414 Section has no content ("Returns")
|
168 | @expect("D414: Section has no content ('Returns')")
169 | def section_underline_overindented_and_contentless(): # noqa: D416
170 | """Toggle the gizmo.
| _____^
171 | |
172 | | Returns
173 | | -------
174 | | """
| |_______^ D414
171 |
172 | Returns
| ^^^^^^^ D414
173 | -------
174 | """
|
sections.py:261:5: D414 Section has no content ("Returns")
sections.py:266:5: D414 Section has no content ("Returns")
|
259 | @expect("D414: Section has no content ('Returns')")
260 | def valid_google_style_section(): # noqa: D406, D407
261 | """Toggle the gizmo.
| _____^
262 | |
263 | | Args:
264 | | note: A random string.
265 | |
266 | | Returns:
267 | |
268 | | Raises:
269 | | RandomError: A random error that occurs randomly.
270 | |
271 | | """
| |_______^ D414
264 | note: A random string.
265 |
266 | Returns:
| ^^^^^^^ D414
267 |
268 | Raises:
|
sections.py:558:5: D414 Section has no content ("Returns")
sections.py:563:9: D414 Section has no content ("Returns")
|
557 | def titlecase_sub_section_header():
558 | """Below, `Returns:` should be considered a section header.
| _____^
559 | |
560 | | Args:
561 | | Here's a note.
562 | |
563 | | Returns:
564 | | """
| |_______^ D414
561 | Here's a note.
562 |
563 | Returns:
| ^^^^^^^ D414
564 | """
|