From bfae1f1412d60fec43c3b0b7123d64e5505c82f8 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 3 Dec 2023 15:45:30 -0500 Subject: [PATCH] Convert over-indentation rule to use number of characters (#8983) Closes https://github.com/astral-sh/ruff/issues/8978. --- .../test/fixtures/pydocstyle/D208.py | 6 ++++ .../src/rules/pydocstyle/rules/indent.rs | 28 +++++++++---------- ...ules__pydocstyle__tests__D208_D208.py.snap | 6 ++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py index 27cc67d056c30..4e99cf4b7fdf5 100644 --- a/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py +++ b/crates/ruff_linter/resources/test/fixtures/pydocstyle/D208.py @@ -8,3 +8,9 @@ class Platform: Args:     Returns: """ + + +def memory_test(): + """ +   参数含义:precision:精确到小数点后几位 + """ diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs index c7220cb0b6181..1c2ced8bd1b0d 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/indent.rs @@ -172,8 +172,9 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { let mut has_seen_tab = docstring.indentation.contains('\t'); let mut is_over_indented = true; let mut over_indented_lines = vec![]; - let mut over_indented_offset = usize::MAX; + let mut over_indented_size = usize::MAX; + let docstring_indent_size = docstring.indentation.chars().count(); for i in 0..lines.len() { // First lines and continuations doesn't need any indentation. if i == 0 || lines[i - 1].ends_with('\\') { @@ -189,6 +190,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { } let line_indent = leading_space(line); + let line_indent_size = line_indent.chars().count(); // We only report tab indentation once, so only check if we haven't seen a tab // yet. @@ -197,9 +199,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { if checker.enabled(Rule::UnderIndentation) { // We report under-indentation on every line. This isn't great, but enables // fix. - if (i == lines.len() - 1 || !is_blank) - && line_indent.len() < docstring.indentation.len() - { + if (i == lines.len() - 1 || !is_blank) && line_indent_size < docstring_indent_size { let mut diagnostic = Diagnostic::new(UnderIndentation, TextRange::empty(line.start())); diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( @@ -217,14 +217,12 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { // until we've viewed all the lines, so for now, just track // the over-indentation status of every line. if i < lines.len() - 1 { - if line_indent.len() > docstring.indentation.len() { + if line_indent_size > docstring_indent_size { over_indented_lines.push(line); // Track the _smallest_ offset we see, in terms of characters. - over_indented_offset = std::cmp::min( - line_indent.chars().count() - docstring.indentation.chars().count(), - over_indented_offset, - ); + over_indented_size = + std::cmp::min(line_indent_size - docstring_indent_size, over_indented_size); } else { is_over_indented = false; } @@ -250,6 +248,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { // enables the fix capability. let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(line.start())); + let edit = if indent.is_empty() { // Delete the entire indent. Edit::range_deletion(TextRange::at(line.start(), line_indent.text_len())) @@ -259,13 +258,11 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { .locator() .after(line.start() + indent.text_len()) .chars() - .take(over_indented_offset) + .take(over_indented_size) .map(TextLen::text_len) .sum::(); - Edit::range_replacement( - indent.clone(), - TextRange::at(line.start(), indent.text_len() + offset), - ) + let range = TextRange::at(line.start(), indent.text_len() + offset); + Edit::range_replacement(indent, range) }; diagnostic.set_fix(Fix::safe_edit(edit)); checker.diagnostics.push(diagnostic); @@ -275,7 +272,8 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) { // If the last line is over-indented... if let Some(last) = lines.last() { let line_indent = leading_space(last); - if line_indent.len() > docstring.indentation.len() { + let line_indent_size = line_indent.chars().count(); + if line_indent_size > docstring_indent_size { let mut diagnostic = Diagnostic::new(OverIndentation, TextRange::empty(last.start())); let indent = clean_space(docstring.indentation); diff --git a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap index 944cbb9d520b0..517dc3802e1ec 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap +++ b/crates/ruff_linter/src/rules/pydocstyle/snapshots/ruff_linter__rules__pydocstyle__tests__D208_D208.py.snap @@ -37,6 +37,7 @@ D208.py:8:1: D208 [*] Docstring is over-indented 8 |+ Args: 9 9 |     Returns: 10 10 | """ +11 11 | D208.py:9:1: D208 [*] Docstring is over-indented | @@ -55,6 +56,8 @@ D208.py:9:1: D208 [*] Docstring is over-indented 9 |-     Returns: 9 |+ Returns: 10 10 | """ +11 11 | +12 12 | D208.py:10:1: D208 [*] Docstring is over-indented | @@ -71,5 +74,8 @@ D208.py:10:1: D208 [*] Docstring is over-indented 9 9 |     Returns: 10 |- """ 10 |+ """ +11 11 | +12 12 | +13 13 | def memory_test():