diff --git a/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_1.py b/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_1.py new file mode 100644 index 0000000000..4cd40b5af6 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_1.py @@ -0,0 +1,7 @@ +"""Case: There's a random import, so it should add `contextlib` after it.""" +import math + +try: + math.sqrt(-1) +except ValueError: # SIM105 + pass diff --git a/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_2.py b/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_2.py new file mode 100644 index 0000000000..66a9ba35c0 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_simplify/SIM105_2.py @@ -0,0 +1,12 @@ +"""Case: `contextlib` already imported.""" +import contextlib + + +def foo(): + pass + + +try: + foo() +except ValueError: + pass diff --git a/crates/ruff/src/importer.rs b/crates/ruff/src/importer.rs index db929307a1..fe003d1819 100644 --- a/crates/ruff/src/importer.rs +++ b/crates/ruff/src/importer.rs @@ -156,7 +156,7 @@ fn match_docstring_end(body: &[Stmt]) -> Option { Some(stmt.end()) } -/// Find the location at which a "top-of-file" import should be inserted, +/// Find the location at which an "end-of-statement" import should be inserted, /// along with a prefix and suffix to use for the insertion. /// /// For example, given the following code: @@ -165,9 +165,15 @@ fn match_docstring_end(body: &[Stmt]) -> Option { /// """Hello, world!""" /// /// import os +/// import math +/// +/// +/// def foo(): +/// pass /// ``` /// -/// The location returned will be the start of the `import os` statement, +/// The location returned will be the start of new line after the last +/// import statement, which in this case is the line after `import math`, /// along with a trailing newline suffix. fn end_of_statement_insertion(stmt: &Stmt, locator: &Locator, stylist: &Stylist) -> Insertion { let location = stmt.end(); @@ -180,7 +186,7 @@ fn end_of_statement_insertion(stmt: &Stmt, locator: &Locator, stylist: &Stylist) // Otherwise, insert on the next line. Insertion::new( "", - locator.line_end(location), + locator.full_line_end(location), stylist.line_ending().as_str(), ) } diff --git a/crates/ruff/src/rules/flake8_simplify/mod.rs b/crates/ruff/src/rules/flake8_simplify/mod.rs index 92c86353b8..abec6560e9 100644 --- a/crates/ruff/src/rules/flake8_simplify/mod.rs +++ b/crates/ruff/src/rules/flake8_simplify/mod.rs @@ -17,6 +17,8 @@ mod tests { #[test_case(Rule::CollapsibleIf, Path::new("SIM102.py"); "SIM102")] #[test_case(Rule::NeedlessBool, Path::new("SIM103.py"); "SIM103")] #[test_case(Rule::SuppressibleException, Path::new("SIM105.py"); "SIM105")] + #[test_case(Rule::SuppressibleException, Path::new("SIM105_1.py"); "SIM105_1")] + #[test_case(Rule::SuppressibleException, Path::new("SIM105_2.py"); "SIM105_2")] #[test_case(Rule::ReturnInTryExceptFinally, Path::new("SIM107.py"); "SIM107")] #[test_case(Rule::IfElseBlockInsteadOfIfExp, Path::new("SIM108.py"); "SIM108")] #[test_case(Rule::CompareWithTuple, Path::new("SIM109.py"); "SIM109")] diff --git a/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_1.py.snap b/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_1.py.snap new file mode 100644 index 0000000000..fd36496c68 --- /dev/null +++ b/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_1.py.snap @@ -0,0 +1,28 @@ +--- +source: crates/ruff/src/rules/flake8_simplify/mod.rs +--- +SIM105_1.py:4:1: SIM105 [*] Use `contextlib.suppress(ValueError)` instead of `try`-`except`-`pass` + | +4 | import math +5 | +6 | / try: +7 | | math.sqrt(-1) +8 | | except ValueError: # SIM105 +9 | | pass + | |________^ SIM105 + | + = help: Replace with `contextlib.suppress(ValueError)` + +ℹ Suggested fix +1 1 | """Case: There's a random import, so it should add `contextlib` after it.""" +2 2 | import math + 3 |+import contextlib +3 4 | +4 |-try: + 5 |+with contextlib.suppress(ValueError): +5 6 | math.sqrt(-1) +6 |-except ValueError: # SIM105 +7 |- pass + 7 |+ + + diff --git a/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_2.py.snap b/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_2.py.snap new file mode 100644 index 0000000000..0648bce468 --- /dev/null +++ b/crates/ruff/src/rules/flake8_simplify/snapshots/ruff__rules__flake8_simplify__tests__SIM105_SIM105_2.py.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff/src/rules/flake8_simplify/mod.rs +--- +SIM105_2.py:9:1: SIM105 [*] Use `contextlib.suppress(ValueError)` instead of `try`-`except`-`pass` + | + 9 | / try: +10 | | foo() +11 | | except ValueError: +12 | | pass + | |________^ SIM105 + | + = help: Replace with `contextlib.suppress(ValueError)` + +ℹ Suggested fix +6 6 | pass +7 7 | +8 8 | +9 |-try: + 9 |+with contextlib.suppress(ValueError): +10 10 | foo() +11 |-except ValueError: +12 |- pass + 11 |+ + +