From 828871dc5c3ba336a31e881b3a7f2deeea6c9da0 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 30 Aug 2024 19:39:00 -0400 Subject: [PATCH] [`pyupgrade`] Detect `aiofiles.open` calls in `UP015` (#13173) ## Summary Closes https://github.com/astral-sh/ruff/issues/12879. --- .../test/fixtures/pyupgrade/UP015.py | 7 +++ .../pyupgrade/rules/redundant_open_modes.rs | 11 +++- ...er__rules__pyupgrade__tests__UP015.py.snap | 51 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py index 2413407ed6ba4..9f78caef4cddd 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP015.py @@ -78,3 +78,10 @@ open("foo", "rt") open("f", "r", encoding="UTF-8") open("f", "wt") + + +import aiofiles + +aiofiles.open("foo", "U") +aiofiles.open("foo", "r") +aiofiles.open("foo", mode="r") diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs index 50f35ce5d17f5..3939d3e321a51 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/redundant_open_modes.rs @@ -61,7 +61,16 @@ impl AlwaysFixableViolation for RedundantOpenModes { /// UP015 pub(crate) fn redundant_open_modes(checker: &mut Checker, call: &ast::ExprCall) { - if !checker.semantic().match_builtin_expr(&call.func, "open") { + if !checker + .semantic() + .resolve_qualified_name(&call.func) + .is_some_and(|qualified_name| { + matches!( + qualified_name.segments(), + ["" | "builtins" | "aiofiles", "open"] + ) + }) + { return; } diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap index d85977a74ec80..054bc00ec8c73 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP015.py.snap @@ -899,4 +899,55 @@ UP015.py:70:1: UP015 [*] Unnecessary open mode parameters, use ""rb"" 72 72 | open = 1 73 73 | open("foo", "U") +UP015.py:85:1: UP015 [*] Unnecessary open mode parameters + | +83 | import aiofiles +84 | +85 | aiofiles.open("foo", "U") + | ^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +86 | aiofiles.open("foo", "r") +87 | aiofiles.open("foo", mode="r") + | + = help: Remove open mode parameters + +ℹ Safe fix +82 82 | +83 83 | import aiofiles +84 84 | +85 |-aiofiles.open("foo", "U") + 85 |+aiofiles.open("foo") +86 86 | aiofiles.open("foo", "r") +87 87 | aiofiles.open("foo", mode="r") + +UP015.py:86:1: UP015 [*] Unnecessary open mode parameters + | +85 | aiofiles.open("foo", "U") +86 | aiofiles.open("foo", "r") + | ^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 +87 | aiofiles.open("foo", mode="r") + | + = help: Remove open mode parameters + +ℹ Safe fix +83 83 | import aiofiles +84 84 | +85 85 | aiofiles.open("foo", "U") +86 |-aiofiles.open("foo", "r") + 86 |+aiofiles.open("foo") +87 87 | aiofiles.open("foo", mode="r") + +UP015.py:87:1: UP015 [*] Unnecessary open mode parameters + | +85 | aiofiles.open("foo", "U") +86 | aiofiles.open("foo", "r") +87 | aiofiles.open("foo", mode="r") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP015 + | + = help: Remove open mode parameters +ℹ Safe fix +84 84 | +85 85 | aiofiles.open("foo", "U") +86 86 | aiofiles.open("foo", "r") +87 |-aiofiles.open("foo", mode="r") + 87 |+aiofiles.open("foo")