From 717128112d027f970a9b1aa093d06a81e3ddb9ac Mon Sep 17 00:00:00 2001 From: Zanie Adkins Date: Thu, 4 May 2023 13:42:34 -0500 Subject: [PATCH] Fix panic in pydocstyle D214 when docstring indentation is empty (#4216) --- .../test/fixtures/pydocstyle/D214_module.py | 21 +++++++ crates/ruff/src/rules/pydocstyle/mod.rs | 1 + .../src/rules/pydocstyle/rules/sections.rs | 12 ++-- ...ydocstyle__tests__D214_D214_module.py.snap | 59 +++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 crates/ruff/resources/test/fixtures/pydocstyle/D214_module.py create mode 100644 crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D214_D214_module.py.snap diff --git a/crates/ruff/resources/test/fixtures/pydocstyle/D214_module.py b/crates/ruff/resources/test/fixtures/pydocstyle/D214_module.py new file mode 100644 index 0000000000000..9e2ae69174ccb --- /dev/null +++ b/crates/ruff/resources/test/fixtures/pydocstyle/D214_module.py @@ -0,0 +1,21 @@ +"""A module docstring with D214 violations + + Returns +----- + valid returns + + Args +----- + valid args +""" + +import os +from .expected import Expectation + +expectation = Expectation() +expect = expectation.expect + +expect(os.path.normcase(__file__ if __file__[-1] != 'c' else __file__[:-1]), + "D214: Section is over-indented ('Returns')") +expect(os.path.normcase(__file__ if __file__[-1] != 'c' else __file__[:-1]), + "D214: Section is over-indented ('Args')") \ No newline at end of file diff --git a/crates/ruff/src/rules/pydocstyle/mod.rs b/crates/ruff/src/rules/pydocstyle/mod.rs index f56fe1cb24e30..a184174e31b53 100644 --- a/crates/ruff/src/rules/pydocstyle/mod.rs +++ b/crates/ruff/src/rules/pydocstyle/mod.rs @@ -68,6 +68,7 @@ mod tests { #[test_case(Rule::UndocumentedPublicPackage, Path::new("D104/__init__.py"); "D104_1")] #[test_case(Rule::SectionNameEndsInColon, Path::new("D.py"); "D416")] #[test_case(Rule::SectionNotOverIndented, Path::new("sections.py"); "D214")] + #[test_case(Rule::SectionNotOverIndented, Path::new("D214_module.py"); "D214_module")] #[test_case(Rule::SectionUnderlineAfterName, Path::new("sections.py"); "D408")] #[test_case(Rule::SectionUnderlineMatchesSectionLength, Path::new("sections.py"); "D409")] #[test_case(Rule::SectionUnderlineNotOverIndented, Path::new("sections.py"); "D215")] diff --git a/crates/ruff/src/rules/pydocstyle/rules/sections.rs b/crates/ruff/src/rules/pydocstyle/rules/sections.rs index 5a5b55b8b7716..8ba8b443f25fe 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/sections.rs @@ -619,10 +619,14 @@ fn common_section( ); if checker.patch(diagnostic.kind.rule()) { // Replace the existing indentation with whitespace of the appropriate length. - diagnostic.set_fix(Edit::range_replacement( - whitespace::clean(docstring.indentation), - TextRange::at(context.range().start(), leading_space.text_len()), - )); + let content = whitespace::clean(docstring.indentation); + let fix_range = TextRange::at(context.range().start(), leading_space.text_len()); + + diagnostic.set_fix(if content.is_empty() { + Edit::range_deletion(fix_range) + } else { + Edit::range_replacement(content, fix_range) + }); }; checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D214_D214_module.py.snap b/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D214_D214_module.py.snap new file mode 100644 index 0000000000000..bc822b0bb6eaa --- /dev/null +++ b/crates/ruff/src/rules/pydocstyle/snapshots/ruff__rules__pydocstyle__tests__D214_D214_module.py.snap @@ -0,0 +1,59 @@ +--- +source: crates/ruff/src/rules/pydocstyle/mod.rs +--- +D214_module.py:1:1: 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 + | + = help: Remove over-indentation from "Returns" + +ℹ Suggested fix +1 1 | """A module docstring with D214 violations +2 2 | +3 |- Returns + 3 |+Returns +4 4 | ----- +5 5 | valid returns +6 6 | + +D214_module.py:1:1: 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 + | + = help: Remove over-indentation from "Args" + +ℹ Suggested fix +4 4 | ----- +5 5 | valid returns +6 6 | +7 |- Args + 7 |+Args +8 8 | ----- +9 9 | valid args +10 10 | """ + +