From 1ab0273aa7be98f04db0130cb7abd56be83fface Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 18 Jan 2023 12:09:17 -0500 Subject: [PATCH] Strip whitespace when injecting D209 newline (#1967) Closes #1963. --- resources/test/fixtures/pydocstyle/D.py | 9 +++++++++ src/rules/pydocstyle/rules.rs | 17 +++++++++++++++-- ...ff__rules__pydocstyle__tests__D209_D.py.snap | 17 +++++++++++++++++ ...ff__rules__pydocstyle__tests__D213_D.py.snap | 10 ++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/resources/test/fixtures/pydocstyle/D.py b/resources/test/fixtures/pydocstyle/D.py index 30c63e8360..8652ba4a2b 100644 --- a/resources/test/fixtures/pydocstyle/D.py +++ b/resources/test/fixtures/pydocstyle/D.py @@ -579,3 +579,12 @@ def multiline_trailing_and_leading_space(): "or exclamation point (not '\"')") def endswith_quote(): """Whitespace at the end, but also a quote" """ + + +@expect('D209: Multi-line docstring closing quotes should be on a separate ' + 'line') +@expect('D213: Multi-line docstring summary should start at the second line') +def asdfljdjgf24(): + """Summary. + + Description. """ diff --git a/src/rules/pydocstyle/rules.rs b/src/rules/pydocstyle/rules.rs index 38bcfc4e25..040305efca 100644 --- a/src/rules/pydocstyle/rules.rs +++ b/src/rules/pydocstyle/rules.rs @@ -528,12 +528,25 @@ pub fn newline_after_last_paragraph(checker: &mut Checker, docstring: &Docstring ); if checker.patch(diagnostic.kind.code()) { // Insert a newline just before the end-quote(s). + let num_trailing_quotes = "'''".len(); + let num_trailing_spaces = last_line + .chars() + .rev() + .skip(num_trailing_quotes) + .take_while(|c| c.is_whitespace()) + .count(); let content = format!("\n{}", whitespace::clean(docstring.indentation)); - diagnostic.amend(Fix::insertion( + diagnostic.amend(Fix::replacement( content, Location::new( docstring.expr.end_location.unwrap().row(), - docstring.expr.end_location.unwrap().column() - "\"\"\"".len(), + docstring.expr.end_location.unwrap().column() + - num_trailing_spaces + - num_trailing_quotes, + ), + Location::new( + docstring.expr.end_location.unwrap().row(), + docstring.expr.end_location.unwrap().column() - num_trailing_quotes, ), )); } diff --git a/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D209_D.py.snap b/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D209_D.py.snap index 1f181226e8..860a616449 100644 --- a/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D209_D.py.snap +++ b/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D209_D.py.snap @@ -19,4 +19,21 @@ expression: diagnostics row: 283 column: 16 parent: ~ +- kind: + NewLineAfterLastParagraph: ~ + location: + row: 588 + column: 4 + end_location: + row: 590 + column: 21 + fix: + content: "\n " + location: + row: 590 + column: 16 + end_location: + row: 590 + column: 18 + parent: ~ diff --git a/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D213_D.py.snap b/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D213_D.py.snap index c57ecbdd0f..d087881895 100644 --- a/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D213_D.py.snap +++ b/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D213_D.py.snap @@ -192,4 +192,14 @@ expression: diagnostics column: 7 fix: ~ parent: ~ +- kind: + MultiLineSummarySecondLine: ~ + location: + row: 588 + column: 4 + end_location: + row: 590 + column: 21 + fix: ~ + parent: ~