diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_return/RET505.py b/crates/ruff_linter/resources/test/fixtures/flake8_return/RET505.py index f36a19c2ca5f0..ad6fe46c7e29f 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_return/RET505.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_return/RET505.py @@ -198,3 +198,43 @@ def bar9(): def sb(self): if self._sb is not None: return self._sb else: self._sb = '\033[01;%dm'; self._sa = '\033[0;0m'; + + +def indent(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + else: + + c = 3 + return z + + +def indent(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + else: + # comment + c = 3 + return z + + +def indent(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + else: + # comment + c = 3 + return z + + +def indent(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + else: + # comment + c = 3 + return z diff --git a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET505_RET505.py.snap b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET505_RET505.py.snap index bb4d283029aec..c3fd9c8b12e10 100644 --- a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET505_RET505.py.snap +++ b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__RET505_RET505.py.snap @@ -171,4 +171,48 @@ RET505.py:200:5: RET505 Unnecessary `else` after `return` statement | = help: Remove unnecessary `else` +RET505.py:207:5: RET505 Unnecessary `else` after `return` statement + | +205 | a = 1 +206 | return y +207 | else: + | ^^^^ RET505 +208 | +209 | c = 3 + | + = help: Remove unnecessary `else` + +RET505.py:217:5: RET505 Unnecessary `else` after `return` statement + | +215 | a = 1 +216 | return y +217 | else: + | ^^^^ RET505 +218 | # comment +219 | c = 3 + | + = help: Remove unnecessary `else` + +RET505.py:227:5: RET505 Unnecessary `else` after `return` statement + | +225 | a = 1 +226 | return y +227 | else: + | ^^^^ RET505 +228 | # comment +229 | c = 3 + | + = help: Remove unnecessary `else` + +RET505.py:237:5: RET505 Unnecessary `else` after `return` statement + | +235 | a = 1 +236 | return y +237 | else: + | ^^^^ RET505 +238 | # comment +239 | c = 3 + | + = help: Remove unnecessary `else` + diff --git a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__preview__RET505_RET505.py.snap b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__preview__RET505_RET505.py.snap index 7f57b62a558ab..21a3d2efc6fd3 100644 --- a/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__preview__RET505_RET505.py.snap +++ b/crates/ruff_linter/src/rules/flake8_return/snapshots/ruff_linter__rules__flake8_return__tests__preview__RET505_RET505.py.snap @@ -358,5 +358,107 @@ RET505.py:200:5: RET505 [*] Unnecessary `else` after `return` statement 199 199 | if self._sb is not None: return self._sb 200 |- else: self._sb = '\033[01;%dm'; self._sa = '\033[0;0m'; 200 |+ self._sb = '\033[01;%dm'; self._sa = '\033[0;0m'; +201 201 | +202 202 | +203 203 | def indent(x, y, w, z): + +RET505.py:207:5: RET505 [*] Unnecessary `else` after `return` statement + | +205 | a = 1 +206 | return y +207 | else: + | ^^^^ RET505 +208 | +209 | c = 3 + | + = help: Remove unnecessary `else` + +ℹ Safe fix +204 204 | if x: # [no-else-return] +205 205 | a = 1 +206 206 | return y +207 |- else: +208 207 | +209 |- c = 3 +210 |- return z + 208 |+ c = 3 + 209 |+ return z +211 210 | +212 211 | +213 212 | def indent(x, y, w, z): + +RET505.py:217:5: RET505 [*] Unnecessary `else` after `return` statement + | +215 | a = 1 +216 | return y +217 | else: + | ^^^^ RET505 +218 | # comment +219 | c = 3 + | + = help: Remove unnecessary `else` + +ℹ Safe fix +214 214 | if x: # [no-else-return] +215 215 | a = 1 +216 216 | return y +217 |- else: +218 |- # comment +219 |- c = 3 +220 |- return z + 217 |+ # comment + 218 |+ c = 3 + 219 |+ return z +221 220 | +222 221 | +223 222 | def indent(x, y, w, z): + +RET505.py:227:5: RET505 [*] Unnecessary `else` after `return` statement + | +225 | a = 1 +226 | return y +227 | else: + | ^^^^ RET505 +228 | # comment +229 | c = 3 + | + = help: Remove unnecessary `else` + +ℹ Safe fix +224 224 | if x: # [no-else-return] +225 225 | a = 1 +226 226 | return y +227 |- else: +228 |- # comment +229 |- c = 3 +230 |- return z + 227 |+ # comment + 228 |+ c = 3 + 229 |+ return z +231 230 | +232 231 | +233 232 | def indent(x, y, w, z): + +RET505.py:237:5: RET505 [*] Unnecessary `else` after `return` statement + | +235 | a = 1 +236 | return y +237 | else: + | ^^^^ RET505 +238 | # comment +239 | c = 3 + | + = help: Remove unnecessary `else` + +ℹ Safe fix +234 234 | if x: # [no-else-return] +235 235 | a = 1 +236 236 | return y +237 |- else: +238 237 | # comment +239 |- c = 3 +240 |- return z + 238 |+ c = 3 + 239 |+ return z diff --git a/crates/ruff_python_trivia/src/textwrap.rs b/crates/ruff_python_trivia/src/textwrap.rs index 681a17016e1e7..9671fcecc244e 100644 --- a/crates/ruff_python_trivia/src/textwrap.rs +++ b/crates/ruff_python_trivia/src/textwrap.rs @@ -138,11 +138,18 @@ pub fn dedent(text: &str) -> Cow<'_, str> { /// # Panics /// If the first line is indented by less than the provided indent. pub fn dedent_to(text: &str, indent: &str) -> String { - // Look at the indentation of the first line, to determine the "baseline" indentation. + // Look at the indentation of the first non-empty line, to determine the "baseline" indentation. let existing_indent_len = text .universal_newlines() - .next() - .map_or(0, |line| line.len() - line.trim_start().len()); + .find_map(|line| { + let trimmed = line.trim_whitespace_start(); + if trimmed.is_empty() || trimmed.starts_with('#') { + None + } else { + Some(line.len() - trimmed.len()) + } + }) + .unwrap_or_default(); // Determine the amount of indentation to remove. let dedent_len = existing_indent_len - indent.len();