diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP020.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP020.py index 00c8f30239094..92e5947eba0d1 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP020.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP020.py @@ -7,3 +7,11 @@ with open("f.txt") as f: print(f.read()) + + +with ( + io # text + # text + .open("file.txt") as f +): + ... diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs index 563658fa66e3a..4939511534e1c 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/open_alias.rs @@ -1,3 +1,4 @@ +use ruff_diagnostics::Applicability; use ruff_python_ast::Expr; use ruff_macros::{ViolationMetadata, derive_message_formats}; @@ -26,6 +27,8 @@ use crate::{Edit, Fix, FixAvailability, Violation}; /// with open("file.txt") as f: /// ... /// ``` +/// ## Fix safety +/// This rule's fix is marked as safe, unless the expression contains comments. /// /// ## References /// - [Python documentation: `io.open`](https://docs.python.org/3/library/io.html#io.open) @@ -60,9 +63,17 @@ pub(crate) fn open_alias(checker: &Checker, expr: &Expr, func: &Expr) { expr.start(), checker.semantic(), )?; - Ok(Fix::safe_edits( + + let applicability = if checker.comment_ranges().intersects(func.range()) { + Applicability::Unsafe + } else { + Applicability::Safe + }; + + Ok(Fix::applicable_edits( Edit::range_replacement(binding, func.range()), import_edit, + applicability, )) }); } diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap index 0d816f52ac5d3..74b1d168f24e5 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP020.py.snap @@ -37,3 +37,35 @@ help: Replace with builtin `open` - with open("f.txt") as f: 9 + with builtins.open("f.txt") as f: 10 | print(f.read()) +11 | +12 | + +UP020 [*] Use builtin `open` + --> UP020.py:13:5 + | +12 | with ( +13 | / io # text +14 | | # text +15 | | .open("file.txt") as f + | |_____________________^ +16 | ): +17 | ... + | +help: Replace with builtin `open` +4 | print(f.read()) +5 | +6 | from io import open +7 + import builtins +8 | +9 | with open("f.txt") as f: +10 | print(f.read()) +11 | +12 | +13 | with ( + - io # text + - # text + - .open("file.txt") as f +14 + builtins.open("file.txt") as f +15 | ): +16 | ... +note: This is an unsafe fix and may change runtime behavior