Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pydocstyle] Re-implement last-line-after-section (D413) #9654

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 59 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pydocstyle/D413.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Do something.

Args:
x: the value
with a hanging indent

Returns:
the value
"""


def func():
"""Do something.

Args:
x: the value
with a hanging indent

Returns:
the value
"""


def func():
"""Do something.

Args:
x: the value
with a hanging indent

Returns:
the value

"""


def func():
"""Do something.

Args:
x: the value
with a hanging indent

Returns:
the value


"""


def func():
"""Do something.

Args:
x: the value
with a hanging indent

Returns:
the value"""
1 change: 1 addition & 0 deletions crates/ruff_linter/src/rules/pydocstyle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod tests {

#[test_case(Rule::BlankLineAfterLastSection, Path::new("sections.py"))]
#[test_case(Rule::NoBlankLineAfterSection, Path::new("sections.py"))]
#[test_case(Rule::BlankLineAfterLastSection, Path::new("D413.py"))]
#[test_case(Rule::BlankLineAfterSummary, Path::new("D.py"))]
#[test_case(Rule::NoBlankLineBeforeSection, Path::new("sections.py"))]
#[test_case(Rule::CapitalizeSectionName, Path::new("sections.py"))]
Expand Down
27 changes: 22 additions & 5 deletions crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1632,9 +1632,13 @@ fn common_section(
}

let line_end = checker.stylist().line_ending().as_str();
let last_line = context.following_lines().last();
if last_line.map_or(true, |line| !line.trim().is_empty()) {
if let Some(next) = next {

if let Some(next) = next {
if context
.following_lines()
.last()
.map_or(true, |line| !line.trim().is_empty())
{
if checker.enabled(Rule::NoBlankLineAfterSection) {
let mut diagnostic = Diagnostic::new(
NoBlankLineAfterSection {
Expand All @@ -1649,7 +1653,16 @@ fn common_section(
)));
checker.diagnostics.push(diagnostic);
}
} else {
}
} else {
// The first blank line is the line containing the closing triple quotes, so we need at
// least two.
let num_blank_lines = context
.following_lines()
.rev()
.take_while(|line| line.trim().is_empty())
.count();
if num_blank_lines < 2 {
if checker.enabled(Rule::BlankLineAfterLastSection) {
let mut diagnostic = Diagnostic::new(
BlankLineAfterLastSection {
Expand All @@ -1659,7 +1672,11 @@ fn common_section(
);
// Add a newline after the section.
diagnostic.set_fix(Fix::safe_edit(Edit::insertion(
format!("{}{}", line_end, docstring.indentation),
format!(
"{}{}",
line_end.repeat(2 - num_blank_lines),
docstring.indentation
),
context.end(),
)));
checker.diagnostics.push(diagnostic);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---
D413.py:1: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
|
= help: Add blank line after "Returns"

ℹ Safe fix
6 6 |
7 7 | Returns:
8 8 | the value
9 |+
10 |+
9 11 | """
10 12 |
11 13 |

D413.py:13: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
|
= help: Add blank line after "Returns"

ℹ Safe fix
18 18 |
19 19 | Returns:
20 20 | the value
21 |+
21 22 | """
22 23 |
23 24 |

D413.py:52: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
|
= help: Add blank line after "Returns"

ℹ Safe fix
56 56 | with a hanging indent
57 57 |
58 58 | Returns:
59 |- the value"""
59 |+ the value
60 |+
61 |+ """


Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,147 @@ sections.py:65:5: D413 [*] Missing blank line after last section ("Returns")
66 66 |
67 |- Returns"""
67 |+ Returns
68 |+ """
68 69 |
69 70 |
70 71 | @expect(_D213)
68 |+
69 |+ """
68 70 |
69 71 |
70 72 | @expect(_D213)

sections.py:120: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
|
= help: Add blank line after "Returns"

ℹ Safe fix
122 122 | Returns
123 123 | -------
124 124 | A value of some sort.
125 |+
125 126 | """
126 127 |
127 128 |

sections.py:170: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
|
= help: Add blank line after "Returns"

ℹ Safe fix
171 171 |
172 172 | Returns
173 173 | -------
174 |+
174 175 | """
175 176 |
176 177 |

sections.py:519: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
|
= help: Add blank line after "Parameters"

ℹ Safe fix
520 520 |
521 521 | Parameters
522 522 | ==========
523 |+
523 524 | """
524 525 |
525 526 |

sections.py:527: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
|
= help: Add blank line after "Parameters"

ℹ Safe fix
528 528 |
529 529 | Parameters
530 530 | ===========
531 |+
531 532 | """
532 533 |
533 534 |

sections.py:548: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
|
= help: Add blank line after "Args"

ℹ Safe fix
551 551 | Here's a note.
552 552 |
553 553 | returns:
554 |+
554 555 | """
555 556 |
556 557 |

sections.py:558:5: 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
|
= help: Add blank line after "Returns"

ℹ Safe fix
561 561 | Here's a note.
562 562 |
563 563 | Returns:
564 |+
564 565 | """