From 276f1d0d88d7815f70fabb712af44bb4de85d9a7 Mon Sep 17 00:00:00 2001 From: Brent Westbrook <36778786+ntBre@users.noreply.github.com> Date: Fri, 7 Nov 2025 12:47:21 -0500 Subject: [PATCH] Remove duplicate preview tests for `FURB101` and `FURB103` (#21303) Summary -- These rules are themselves in preview, so we don't need the additional preview checks on the fixes or the separate preview tests. This has confused me in a couple of reviews of changes to the fixes. Test Plan -- Existing tests, with the fixes previously only shown in the preview tests now in the "non-preview" tests. --- crates/ruff_linter/src/preview.rs | 10 - crates/ruff_linter/src/rules/refurb/mod.rs | 20 -- .../src/rules/refurb/rules/read_whole_file.rs | 4 - .../rules/refurb/rules/write_whole_file.rs | 4 - ...es__refurb__tests__FURB101_FURB101.py.snap | 97 +++++- ...es__refurb__tests__FURB103_FURB103.py.snap | 154 +++++++++- ...rb__tests__preview_FURB101_FURB101.py.snap | 191 ------------ ...rb__tests__preview_FURB103_FURB103.py.snap | 281 ------------------ ...rb__tests__write_whole_file_python_39.snap | 108 ++++++- 9 files changed, 336 insertions(+), 533 deletions(-) delete mode 100644 crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB101_FURB101.py.snap delete mode 100644 crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB103_FURB103.py.snap diff --git a/crates/ruff_linter/src/preview.rs b/crates/ruff_linter/src/preview.rs index d84035c762..836ba4feea 100644 --- a/crates/ruff_linter/src/preview.rs +++ b/crates/ruff_linter/src/preview.rs @@ -261,16 +261,6 @@ pub(crate) const fn is_b006_unsafe_fix_preserve_assignment_expr_enabled( settings.preview.is_enabled() } -// https://github.com/astral-sh/ruff/pull/20520 -pub(crate) const fn is_fix_read_whole_file_enabled(settings: &LinterSettings) -> bool { - settings.preview.is_enabled() -} - -// https://github.com/astral-sh/ruff/pull/20520 -pub(crate) const fn is_fix_write_whole_file_enabled(settings: &LinterSettings) -> bool { - settings.preview.is_enabled() -} - pub(crate) const fn is_typing_extensions_str_alias_enabled(settings: &LinterSettings) -> bool { settings.preview.is_enabled() } diff --git a/crates/ruff_linter/src/rules/refurb/mod.rs b/crates/ruff_linter/src/rules/refurb/mod.rs index 97d9fae7a6..9187853141 100644 --- a/crates/ruff_linter/src/rules/refurb/mod.rs +++ b/crates/ruff_linter/src/rules/refurb/mod.rs @@ -12,7 +12,6 @@ mod tests { use test_case::test_case; use crate::registry::Rule; - use crate::settings::types::PreviewMode; use crate::test::test_path; use crate::{assert_diagnostics, settings}; @@ -63,25 +62,6 @@ mod tests { Ok(()) } - #[test_case(Rule::ReadWholeFile, Path::new("FURB101.py"))] - #[test_case(Rule::WriteWholeFile, Path::new("FURB103.py"))] - fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> { - let snapshot = format!( - "preview_{}_{}", - rule_code.noqa_code(), - path.to_string_lossy() - ); - let diagnostics = test_path( - Path::new("refurb").join(path).as_path(), - &settings::LinterSettings { - preview: PreviewMode::Enabled, - ..settings::LinterSettings::for_rule(rule_code) - }, - )?; - assert_diagnostics!(snapshot, diagnostics); - Ok(()) - } - #[test] fn write_whole_file_python_39() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs index b64f91829a..279ecb66aa 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/read_whole_file.rs @@ -125,10 +125,6 @@ impl<'a> Visitor<'a> for ReadMatcher<'a, '_> { open.item.range(), ); - if !crate::preview::is_fix_read_whole_file_enabled(self.checker.settings()) { - return; - } - let target = match self.with_stmt.body.first() { Some(Stmt::Assign(assign)) if assign.value.range().contains_range(expr.range()) => diff --git a/crates/ruff_linter/src/rules/refurb/rules/write_whole_file.rs b/crates/ruff_linter/src/rules/refurb/rules/write_whole_file.rs index da99733efd..f25faa3eb2 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/write_whole_file.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/write_whole_file.rs @@ -141,10 +141,6 @@ impl<'a> Visitor<'a> for WriteMatcher<'a, '_> { open.item.range(), ); - if !crate::preview::is_fix_write_whole_file_enabled(self.checker.settings()) { - return; - } - if let Some(fix) = generate_fix(self.checker, &open, self.with_stmt, &suggestion) { diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap index 3f851c3f12..4131499c0c 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB101_FURB101.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/refurb/mod.rs --- -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text()` --> FURB101.py:12:6 | 11 | # FURB101 @@ -10,8 +10,22 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` 13 | x = f.read() | help: Replace with `Path("file.txt").read_text()` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +10 | # Errors. +11 | +12 | # FURB101 + - with open("file.txt") as f: + - x = f.read() +13 + x = pathlib.Path("file.txt").read_text() +14 | +15 | # FURB101 +16 | with open("file.txt", "rb") as f: -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_bytes()` --> FURB101.py:16:6 | 15 | # FURB101 @@ -20,8 +34,22 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` 17 | x = f.read() | help: Replace with `Path("file.txt").read_bytes()` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +14 | x = f.read() +15 | +16 | # FURB101 + - with open("file.txt", "rb") as f: + - x = f.read() +17 + x = pathlib.Path("file.txt").read_bytes() +18 | +19 | # FURB101 +20 | with open("file.txt", mode="rb") as f: -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_bytes()` --> FURB101.py:20:6 | 19 | # FURB101 @@ -30,8 +58,22 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_bytes()` 21 | x = f.read() | help: Replace with `Path("file.txt").read_bytes()` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +18 | x = f.read() +19 | +20 | # FURB101 + - with open("file.txt", mode="rb") as f: + - x = f.read() +21 + x = pathlib.Path("file.txt").read_bytes() +22 | +23 | # FURB101 +24 | with open("file.txt", encoding="utf8") as f: -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(encoding="utf8")` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text(encoding="utf8")` --> FURB101.py:24:6 | 23 | # FURB101 @@ -40,8 +82,22 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(enco 25 | x = f.read() | help: Replace with `Path("file.txt").read_text(encoding="utf8")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +22 | x = f.read() +23 | +24 | # FURB101 + - with open("file.txt", encoding="utf8") as f: + - x = f.read() +25 + x = pathlib.Path("file.txt").read_text(encoding="utf8") +26 | +27 | # FURB101 +28 | with open("file.txt", errors="ignore") as f: -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(errors="ignore")` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text(errors="ignore")` --> FURB101.py:28:6 | 27 | # FURB101 @@ -50,8 +106,22 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text(erro 29 | x = f.read() | help: Replace with `Path("file.txt").read_text(errors="ignore")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +26 | x = f.read() +27 | +28 | # FURB101 + - with open("file.txt", errors="ignore") as f: + - x = f.read() +29 + x = pathlib.Path("file.txt").read_text(errors="ignore") +30 | +31 | # FURB101 +32 | with open("file.txt", mode="r") as f: # noqa: FURB120 -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` +FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text()` --> FURB101.py:32:6 | 31 | # FURB101 @@ -60,6 +130,21 @@ FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` 33 | x = f.read() | help: Replace with `Path("file.txt").read_text()` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +30 | x = f.read() +31 | +32 | # FURB101 + - with open("file.txt", mode="r") as f: # noqa: FURB120 + - x = f.read() +33 + x = pathlib.Path("file.txt").read_text() +34 | +35 | # FURB101 +36 | with open(foo(), "rb") as f: +note: This is an unsafe fix and may change runtime behavior FURB101 `open` and `read` should be replaced by `Path(foo()).read_bytes()` --> FURB101.py:36:6 diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB103_FURB103.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB103_FURB103.py.snap index 74f3749953..8148035435 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB103_FURB103.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB103_FURB103.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/refurb/mod.rs --- -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text("test")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text("test")` --> FURB103.py:12:6 | 11 | # FURB103 @@ -10,8 +10,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text("t 13 | f.write("test") | help: Replace with `Path("file.txt").write_text("test")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +10 | # Errors. +11 | +12 | # FURB103 + - with open("file.txt", "w") as f: + - f.write("test") +13 + pathlib.Path("file.txt").write_text("test") +14 | +15 | # FURB103 +16 | with open("file.txt", "wb") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(foobar)` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(foobar)` --> FURB103.py:16:6 | 15 | # FURB103 @@ -20,8 +34,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(f 17 | f.write(foobar) | help: Replace with `Path("file.txt").write_bytes(foobar)` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +14 | f.write("test") +15 | +16 | # FURB103 + - with open("file.txt", "wb") as f: + - f.write(foobar) +17 + pathlib.Path("file.txt").write_bytes(foobar) +18 | +19 | # FURB103 +20 | with open("file.txt", mode="wb") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(b"abc")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(b"abc")` --> FURB103.py:20:6 | 19 | # FURB103 @@ -30,8 +58,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(b 21 | f.write(b"abc") | help: Replace with `Path("file.txt").write_bytes(b"abc")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +18 | f.write(foobar) +19 | +20 | # FURB103 + - with open("file.txt", mode="wb") as f: + - f.write(b"abc") +21 + pathlib.Path("file.txt").write_bytes(b"abc") +22 | +23 | # FURB103 +24 | with open("file.txt", "w", encoding="utf8") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, encoding="utf8")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, encoding="utf8")` --> FURB103.py:24:6 | 23 | # FURB103 @@ -40,8 +82,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 25 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, encoding="utf8")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +22 | f.write(b"abc") +23 | +24 | # FURB103 + - with open("file.txt", "w", encoding="utf8") as f: + - f.write(foobar) +25 + pathlib.Path("file.txt").write_text(foobar, encoding="utf8") +26 | +27 | # FURB103 +28 | with open("file.txt", "w", errors="ignore") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, errors="ignore")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, errors="ignore")` --> FURB103.py:28:6 | 27 | # FURB103 @@ -50,8 +106,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 29 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, errors="ignore")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +26 | f.write(foobar) +27 | +28 | # FURB103 + - with open("file.txt", "w", errors="ignore") as f: + - f.write(foobar) +29 + pathlib.Path("file.txt").write_text(foobar, errors="ignore") +30 | +31 | # FURB103 +32 | with open("file.txt", mode="w") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar)` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar)` --> FURB103.py:32:6 | 31 | # FURB103 @@ -60,6 +130,20 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 33 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar)` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +30 | f.write(foobar) +31 | +32 | # FURB103 + - with open("file.txt", mode="w") as f: + - f.write(foobar) +33 + pathlib.Path("file.txt").write_text(foobar) +34 | +35 | # FURB103 +36 | with open(foo(), "wb") as f: FURB103 `open` and `write` should be replaced by `Path(foo()).write_bytes(bar())` --> FURB103.py:36:6 @@ -105,7 +189,7 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(ba | help: Replace with `Path("file.txt").write_text(bar(bar(a + x)))` -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` --> FURB103.py:58:6 | 57 | # FURB103 @@ -114,8 +198,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 59 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +56 | +57 | +58 | # FURB103 + - with open("file.txt", "w", newline="\r\n") as f: + - f.write(foobar) +59 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") +60 | +61 | +62 | import builtins -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` --> FURB103.py:66:6 | 65 | # FURB103 @@ -124,8 +222,21 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 67 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` +60 | +61 | +62 | import builtins +63 + import pathlib +64 | +65 | +66 | # FURB103 + - with builtins.open("file.txt", "w", newline="\r\n") as f: + - f.write(foobar) +67 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") +68 | +69 | +70 | from builtins import open as o -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` --> FURB103.py:74:6 | 73 | # FURB103 @@ -134,8 +245,21 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 75 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` +68 | +69 | +70 | from builtins import open as o +71 + import pathlib +72 | +73 | +74 | # FURB103 + - with o("file.txt", "w", newline="\r\n") as f: + - f.write(foobar) +75 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") +76 | +77 | # Non-errors. +78 | -FURB103 `open` and `write` should be replaced by `Path("test.json")....` +FURB103 [*] `open` and `write` should be replaced by `Path("test.json")....` --> FURB103.py:154:6 | 152 | data = {"price": 100} @@ -145,3 +269,13 @@ FURB103 `open` and `write` should be replaced by `Path("test.json")....` 155 | f.write(json.dumps(data, indent=4).encode("utf-8")) | help: Replace with `Path("test.json")....` +148 | +149 | # See: https://github.com/astral-sh/ruff/issues/20785 +150 | import json +151 + import pathlib +152 | +153 | data = {"price": 100} +154 | + - with open("test.json", "wb") as f: + - f.write(json.dumps(data, indent=4).encode("utf-8")) +155 + pathlib.Path("test.json").write_bytes(json.dumps(data, indent=4).encode("utf-8")) diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB101_FURB101.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB101_FURB101.py.snap deleted file mode 100644 index 4131499c0c..0000000000 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB101_FURB101.py.snap +++ /dev/null @@ -1,191 +0,0 @@ ---- -source: crates/ruff_linter/src/rules/refurb/mod.rs ---- -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text()` - --> FURB101.py:12:6 - | -11 | # FURB101 -12 | with open("file.txt") as f: - | ^^^^^^^^^^^^^^^^^^^^^ -13 | x = f.read() - | -help: Replace with `Path("file.txt").read_text()` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -10 | # Errors. -11 | -12 | # FURB101 - - with open("file.txt") as f: - - x = f.read() -13 + x = pathlib.Path("file.txt").read_text() -14 | -15 | # FURB101 -16 | with open("file.txt", "rb") as f: - -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_bytes()` - --> FURB101.py:16:6 - | -15 | # FURB101 -16 | with open("file.txt", "rb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -17 | x = f.read() - | -help: Replace with `Path("file.txt").read_bytes()` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -14 | x = f.read() -15 | -16 | # FURB101 - - with open("file.txt", "rb") as f: - - x = f.read() -17 + x = pathlib.Path("file.txt").read_bytes() -18 | -19 | # FURB101 -20 | with open("file.txt", mode="rb") as f: - -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_bytes()` - --> FURB101.py:20:6 - | -19 | # FURB101 -20 | with open("file.txt", mode="rb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -21 | x = f.read() - | -help: Replace with `Path("file.txt").read_bytes()` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -18 | x = f.read() -19 | -20 | # FURB101 - - with open("file.txt", mode="rb") as f: - - x = f.read() -21 + x = pathlib.Path("file.txt").read_bytes() -22 | -23 | # FURB101 -24 | with open("file.txt", encoding="utf8") as f: - -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text(encoding="utf8")` - --> FURB101.py:24:6 - | -23 | # FURB101 -24 | with open("file.txt", encoding="utf8") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -25 | x = f.read() - | -help: Replace with `Path("file.txt").read_text(encoding="utf8")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -22 | x = f.read() -23 | -24 | # FURB101 - - with open("file.txt", encoding="utf8") as f: - - x = f.read() -25 + x = pathlib.Path("file.txt").read_text(encoding="utf8") -26 | -27 | # FURB101 -28 | with open("file.txt", errors="ignore") as f: - -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text(errors="ignore")` - --> FURB101.py:28:6 - | -27 | # FURB101 -28 | with open("file.txt", errors="ignore") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -29 | x = f.read() - | -help: Replace with `Path("file.txt").read_text(errors="ignore")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -26 | x = f.read() -27 | -28 | # FURB101 - - with open("file.txt", errors="ignore") as f: - - x = f.read() -29 + x = pathlib.Path("file.txt").read_text(errors="ignore") -30 | -31 | # FURB101 -32 | with open("file.txt", mode="r") as f: # noqa: FURB120 - -FURB101 [*] `open` and `read` should be replaced by `Path("file.txt").read_text()` - --> FURB101.py:32:6 - | -31 | # FURB101 -32 | with open("file.txt", mode="r") as f: # noqa: FURB120 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -33 | x = f.read() - | -help: Replace with `Path("file.txt").read_text()` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -30 | x = f.read() -31 | -32 | # FURB101 - - with open("file.txt", mode="r") as f: # noqa: FURB120 - - x = f.read() -33 + x = pathlib.Path("file.txt").read_text() -34 | -35 | # FURB101 -36 | with open(foo(), "rb") as f: -note: This is an unsafe fix and may change runtime behavior - -FURB101 `open` and `read` should be replaced by `Path(foo()).read_bytes()` - --> FURB101.py:36:6 - | -35 | # FURB101 -36 | with open(foo(), "rb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^ -37 | # The body of `with` is non-trivial, but the recommendation holds. -38 | bar("pre") - | -help: Replace with `Path(foo()).read_bytes()` - -FURB101 `open` and `read` should be replaced by `Path("a.txt").read_text()` - --> FURB101.py:44:6 - | -43 | # FURB101 -44 | with open("a.txt") as a, open("b.txt", "rb") as b: - | ^^^^^^^^^^^^^^^^^^ -45 | x = a.read() -46 | y = b.read() - | -help: Replace with `Path("a.txt").read_text()` - -FURB101 `open` and `read` should be replaced by `Path("b.txt").read_bytes()` - --> FURB101.py:44:26 - | -43 | # FURB101 -44 | with open("a.txt") as a, open("b.txt", "rb") as b: - | ^^^^^^^^^^^^^^^^^^^^^^^^ -45 | x = a.read() -46 | y = b.read() - | -help: Replace with `Path("b.txt").read_bytes()` - -FURB101 `open` and `read` should be replaced by `Path("file.txt").read_text()` - --> FURB101.py:49:18 - | -48 | # FURB101 -49 | with foo() as a, open("file.txt") as b, foo() as c: - | ^^^^^^^^^^^^^^^^^^^^^ -50 | # We have other things in here, multiple with items, but -51 | # the user reads the whole file and that bit they can replace. - | -help: Replace with `Path("file.txt").read_text()` diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB103_FURB103.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB103_FURB103.py.snap deleted file mode 100644 index 8148035435..0000000000 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__preview_FURB103_FURB103.py.snap +++ /dev/null @@ -1,281 +0,0 @@ ---- -source: crates/ruff_linter/src/rules/refurb/mod.rs ---- -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text("test")` - --> FURB103.py:12:6 - | -11 | # FURB103 -12 | with open("file.txt", "w") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -13 | f.write("test") - | -help: Replace with `Path("file.txt").write_text("test")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -10 | # Errors. -11 | -12 | # FURB103 - - with open("file.txt", "w") as f: - - f.write("test") -13 + pathlib.Path("file.txt").write_text("test") -14 | -15 | # FURB103 -16 | with open("file.txt", "wb") as f: - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(foobar)` - --> FURB103.py:16:6 - | -15 | # FURB103 -16 | with open("file.txt", "wb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -17 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_bytes(foobar)` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -14 | f.write("test") -15 | -16 | # FURB103 - - with open("file.txt", "wb") as f: - - f.write(foobar) -17 + pathlib.Path("file.txt").write_bytes(foobar) -18 | -19 | # FURB103 -20 | with open("file.txt", mode="wb") as f: - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(b"abc")` - --> FURB103.py:20:6 - | -19 | # FURB103 -20 | with open("file.txt", mode="wb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -21 | f.write(b"abc") - | -help: Replace with `Path("file.txt").write_bytes(b"abc")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -18 | f.write(foobar) -19 | -20 | # FURB103 - - with open("file.txt", mode="wb") as f: - - f.write(b"abc") -21 + pathlib.Path("file.txt").write_bytes(b"abc") -22 | -23 | # FURB103 -24 | with open("file.txt", "w", encoding="utf8") as f: - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, encoding="utf8")` - --> FURB103.py:24:6 - | -23 | # FURB103 -24 | with open("file.txt", "w", encoding="utf8") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -25 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar, encoding="utf8")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -22 | f.write(b"abc") -23 | -24 | # FURB103 - - with open("file.txt", "w", encoding="utf8") as f: - - f.write(foobar) -25 + pathlib.Path("file.txt").write_text(foobar, encoding="utf8") -26 | -27 | # FURB103 -28 | with open("file.txt", "w", errors="ignore") as f: - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, errors="ignore")` - --> FURB103.py:28:6 - | -27 | # FURB103 -28 | with open("file.txt", "w", errors="ignore") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -29 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar, errors="ignore")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -26 | f.write(foobar) -27 | -28 | # FURB103 - - with open("file.txt", "w", errors="ignore") as f: - - f.write(foobar) -29 + pathlib.Path("file.txt").write_text(foobar, errors="ignore") -30 | -31 | # FURB103 -32 | with open("file.txt", mode="w") as f: - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar)` - --> FURB103.py:32:6 - | -31 | # FURB103 -32 | with open("file.txt", mode="w") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -33 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar)` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -30 | f.write(foobar) -31 | -32 | # FURB103 - - with open("file.txt", mode="w") as f: - - f.write(foobar) -33 + pathlib.Path("file.txt").write_text(foobar) -34 | -35 | # FURB103 -36 | with open(foo(), "wb") as f: - -FURB103 `open` and `write` should be replaced by `Path(foo()).write_bytes(bar())` - --> FURB103.py:36:6 - | -35 | # FURB103 -36 | with open(foo(), "wb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^ -37 | # The body of `with` is non-trivial, but the recommendation holds. -38 | bar("pre") - | -help: Replace with `Path(foo()).write_bytes(bar())` - -FURB103 `open` and `write` should be replaced by `Path("a.txt").write_text(x)` - --> FURB103.py:44:6 - | -43 | # FURB103 -44 | with open("a.txt", "w") as a, open("b.txt", "wb") as b: - | ^^^^^^^^^^^^^^^^^^^^^^^ -45 | a.write(x) -46 | b.write(y) - | -help: Replace with `Path("a.txt").write_text(x)` - -FURB103 `open` and `write` should be replaced by `Path("b.txt").write_bytes(y)` - --> FURB103.py:44:31 - | -43 | # FURB103 -44 | with open("a.txt", "w") as a, open("b.txt", "wb") as b: - | ^^^^^^^^^^^^^^^^^^^^^^^^ -45 | a.write(x) -46 | b.write(y) - | -help: Replace with `Path("b.txt").write_bytes(y)` - -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(bar(bar(a + x)))` - --> FURB103.py:49:18 - | -48 | # FURB103 -49 | with foo() as a, open("file.txt", "w") as b, foo() as c: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -50 | # We have other things in here, multiple with items, but the user -51 | # writes a single time to file and that bit they can replace. - | -help: Replace with `Path("file.txt").write_text(bar(bar(a + x)))` - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` - --> FURB103.py:58:6 - | -57 | # FURB103 -58 | with open("file.txt", "w", newline="\r\n") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -59 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` -1 + import pathlib -2 | def foo(): -3 | ... -4 | --------------------------------------------------------------------------------- -56 | -57 | -58 | # FURB103 - - with open("file.txt", "w", newline="\r\n") as f: - - f.write(foobar) -59 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") -60 | -61 | -62 | import builtins - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` - --> FURB103.py:66:6 - | -65 | # FURB103 -66 | with builtins.open("file.txt", "w", newline="\r\n") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -67 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` -60 | -61 | -62 | import builtins -63 + import pathlib -64 | -65 | -66 | # FURB103 - - with builtins.open("file.txt", "w", newline="\r\n") as f: - - f.write(foobar) -67 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") -68 | -69 | -70 | from builtins import open as o - -FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, newline="\r\n")` - --> FURB103.py:74:6 - | -73 | # FURB103 -74 | with o("file.txt", "w", newline="\r\n") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -75 | f.write(foobar) - | -help: Replace with `Path("file.txt").write_text(foobar, newline="\r\n")` -68 | -69 | -70 | from builtins import open as o -71 + import pathlib -72 | -73 | -74 | # FURB103 - - with o("file.txt", "w", newline="\r\n") as f: - - f.write(foobar) -75 + pathlib.Path("file.txt").write_text(foobar, newline="\r\n") -76 | -77 | # Non-errors. -78 | - -FURB103 [*] `open` and `write` should be replaced by `Path("test.json")....` - --> FURB103.py:154:6 - | -152 | data = {"price": 100} -153 | -154 | with open("test.json", "wb") as f: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -155 | f.write(json.dumps(data, indent=4).encode("utf-8")) - | -help: Replace with `Path("test.json")....` -148 | -149 | # See: https://github.com/astral-sh/ruff/issues/20785 -150 | import json -151 + import pathlib -152 | -153 | data = {"price": 100} -154 | - - with open("test.json", "wb") as f: - - f.write(json.dumps(data, indent=4).encode("utf-8")) -155 + pathlib.Path("test.json").write_bytes(json.dumps(data, indent=4).encode("utf-8")) diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__write_whole_file_python_39.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__write_whole_file_python_39.snap index 140a274468..3b68b110d5 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__write_whole_file_python_39.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__write_whole_file_python_39.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/refurb/mod.rs --- -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text("test")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text("test")` --> FURB103.py:12:6 | 11 | # FURB103 @@ -10,8 +10,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text("t 13 | f.write("test") | help: Replace with `Path("file.txt").write_text("test")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +10 | # Errors. +11 | +12 | # FURB103 + - with open("file.txt", "w") as f: + - f.write("test") +13 + pathlib.Path("file.txt").write_text("test") +14 | +15 | # FURB103 +16 | with open("file.txt", "wb") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(foobar)` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(foobar)` --> FURB103.py:16:6 | 15 | # FURB103 @@ -20,8 +34,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(f 17 | f.write(foobar) | help: Replace with `Path("file.txt").write_bytes(foobar)` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +14 | f.write("test") +15 | +16 | # FURB103 + - with open("file.txt", "wb") as f: + - f.write(foobar) +17 + pathlib.Path("file.txt").write_bytes(foobar) +18 | +19 | # FURB103 +20 | with open("file.txt", mode="wb") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(b"abc")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_bytes(b"abc")` --> FURB103.py:20:6 | 19 | # FURB103 @@ -30,8 +58,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_bytes(b 21 | f.write(b"abc") | help: Replace with `Path("file.txt").write_bytes(b"abc")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +18 | f.write(foobar) +19 | +20 | # FURB103 + - with open("file.txt", mode="wb") as f: + - f.write(b"abc") +21 + pathlib.Path("file.txt").write_bytes(b"abc") +22 | +23 | # FURB103 +24 | with open("file.txt", "w", encoding="utf8") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, encoding="utf8")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, encoding="utf8")` --> FURB103.py:24:6 | 23 | # FURB103 @@ -40,8 +82,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 25 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, encoding="utf8")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +22 | f.write(b"abc") +23 | +24 | # FURB103 + - with open("file.txt", "w", encoding="utf8") as f: + - f.write(foobar) +25 + pathlib.Path("file.txt").write_text(foobar, encoding="utf8") +26 | +27 | # FURB103 +28 | with open("file.txt", "w", errors="ignore") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, errors="ignore")` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar, errors="ignore")` --> FURB103.py:28:6 | 27 | # FURB103 @@ -50,8 +106,22 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 29 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar, errors="ignore")` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +26 | f.write(foobar) +27 | +28 | # FURB103 + - with open("file.txt", "w", errors="ignore") as f: + - f.write(foobar) +29 + pathlib.Path("file.txt").write_text(foobar, errors="ignore") +30 | +31 | # FURB103 +32 | with open("file.txt", mode="w") as f: -FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(foobar)` +FURB103 [*] `open` and `write` should be replaced by `Path("file.txt").write_text(foobar)` --> FURB103.py:32:6 | 31 | # FURB103 @@ -60,6 +130,20 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(fo 33 | f.write(foobar) | help: Replace with `Path("file.txt").write_text(foobar)` +1 + import pathlib +2 | def foo(): +3 | ... +4 | +-------------------------------------------------------------------------------- +30 | f.write(foobar) +31 | +32 | # FURB103 + - with open("file.txt", mode="w") as f: + - f.write(foobar) +33 + pathlib.Path("file.txt").write_text(foobar) +34 | +35 | # FURB103 +36 | with open(foo(), "wb") as f: FURB103 `open` and `write` should be replaced by `Path(foo()).write_bytes(bar())` --> FURB103.py:36:6 @@ -105,7 +189,7 @@ FURB103 `open` and `write` should be replaced by `Path("file.txt").write_text(ba | help: Replace with `Path("file.txt").write_text(bar(bar(a + x)))` -FURB103 `open` and `write` should be replaced by `Path("test.json")....` +FURB103 [*] `open` and `write` should be replaced by `Path("test.json")....` --> FURB103.py:154:6 | 152 | data = {"price": 100} @@ -115,3 +199,13 @@ FURB103 `open` and `write` should be replaced by `Path("test.json")....` 155 | f.write(json.dumps(data, indent=4).encode("utf-8")) | help: Replace with `Path("test.json")....` +148 | +149 | # See: https://github.com/astral-sh/ruff/issues/20785 +150 | import json +151 + import pathlib +152 | +153 | data = {"price": 100} +154 | + - with open("test.json", "wb") as f: + - f.write(json.dumps(data, indent=4).encode("utf-8")) +155 + pathlib.Path("test.json").write_bytes(json.dumps(data, indent=4).encode("utf-8"))