From 2e2ba2cb16bfa69afe5dbf71cd73445237b3ed99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 19 May 2023 05:11:20 +0300 Subject: [PATCH] Avoid some false positives in dunder variable assigments (#4508) --- .../test/fixtures/pycodestyle/E402.py | 2 +- ...les__pycodestyle__tests__E402_E402.py.snap | 2 +- crates/ruff_python_ast/src/helpers.rs | 24 +++++++++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/pycodestyle/E402.py b/crates/ruff/resources/test/fixtures/pycodestyle/E402.py index b95b2ae1e832a..81e6306c7af11 100644 --- a/crates/ruff/resources/test/fixtures/pycodestyle/E402.py +++ b/crates/ruff/resources/test/fixtures/pycodestyle/E402.py @@ -19,7 +19,7 @@ else: import e -y = x + 1 +__some__magic = 1 import f diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E402_E402.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E402_E402.py.snap index c5ab26ba38029..b2e69a17baac0 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E402_E402.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E402_E402.py.snap @@ -3,7 +3,7 @@ source: crates/ruff/src/rules/pycodestyle/mod.rs --- E402.py:24:1: E402 Module level import not at top of file | -24 | y = x + 1 +24 | __some__magic = 1 25 | 26 | import f | ^^^^^^^^ E402 diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index d064c8f15fb7c..d41e9ad4fb700 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -4,8 +4,6 @@ use std::path::Path; use itertools::Itertools; use log::error; use num_traits::Zero; -use once_cell::sync::Lazy; -use regex::Regex; use ruff_text_size::{TextRange, TextSize}; use rustc_hash::{FxHashMap, FxHashSet}; use rustpython_parser::ast::{ @@ -542,7 +540,9 @@ where body.iter().any(|stmt| any_over_stmt(stmt, func)) } -static DUNDER_REGEX: Lazy = Lazy::new(|| Regex::new(r"__[^\s]+__").unwrap()); +fn is_dunder(id: &str) -> bool { + id.starts_with("__") && id.ends_with("__") +} /// Return `true` if the [`Stmt`] is an assignment to a dunder (like `__all__`). pub fn is_assignment_to_a_dunder(stmt: &Stmt) -> bool { @@ -553,15 +553,19 @@ pub fn is_assignment_to_a_dunder(stmt: &Stmt) -> bool { if targets.len() != 1 { return false; } - match &targets[0] { - Expr::Name(ast::ExprName { id, .. }) => DUNDER_REGEX.is_match(id.as_str()), - _ => false, + if let Expr::Name(ast::ExprName { id, .. }) = &targets[0] { + is_dunder(id) + } else { + false + } + } + Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => { + if let Expr::Name(ast::ExprName { id, .. }) = target.as_ref() { + is_dunder(id) + } else { + false } } - Stmt::AnnAssign(ast::StmtAnnAssign { target, .. }) => match target.as_ref() { - Expr::Name(ast::ExprName { id, .. }) => DUNDER_REGEX.is_match(id.as_str()), - _ => false, - }, _ => false, } }