mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
[refurb
] Minor nits regarding for-loop-writes
and for-loop-set-mutations
(#15958)
This commit is contained in:
parent
827a076a2f
commit
7ca778f492
4 changed files with 49 additions and 25 deletions
|
@ -4,7 +4,8 @@ use ruff_python_ast::{Expr, Stmt, StmtFor};
|
|||
use ruff_python_semantic::analyze::typing;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::refurb::rules::for_loop_writes::parenthesize_loop_iter_if_necessary;
|
||||
|
||||
use super::helpers::parenthesize_loop_iter_if_necessary;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for code that updates a set with the contents of an iterable by
|
||||
|
@ -35,6 +36,10 @@ use crate::rules::refurb::rules::for_loop_writes::parenthesize_loop_iter_if_nece
|
|||
/// s.difference_update((1, 2, 3))
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// The fix will be marked as unsafe if applying the fix would delete any comments.
|
||||
/// Otherwise, it is marked as safe.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `set`](https://docs.python.org/3/library/stdtypes.html#set)
|
||||
#[derive(ViolationMetadata)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
||||
use ruff_python_ast::{Expr, ExprList, ExprName, ExprTuple, Stmt, StmtFor};
|
||||
use ruff_python_semantic::analyze::typing;
|
||||
use ruff_python_semantic::{Binding, ScopeId, SemanticModel, TypingOnlyBindingsStatus};
|
||||
|
@ -8,6 +7,8 @@ use ruff_text_size::{Ranged, TextRange, TextSize};
|
|||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
use super::helpers::parenthesize_loop_iter_if_necessary;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for the use of `IOBase.write` in a for loop.
|
||||
///
|
||||
|
@ -245,26 +246,3 @@ fn loop_variables_are_used_outside_loop(
|
|||
.iter()
|
||||
.any(|name| name_overwrites_outer(name) || name_is_used_later(name))
|
||||
}
|
||||
|
||||
pub(super) fn parenthesize_loop_iter_if_necessary(for_stmt: &StmtFor, checker: &Checker) -> String {
|
||||
let locator = checker.locator();
|
||||
let iter = for_stmt.iter.as_ref();
|
||||
|
||||
let original_parenthesized_range = parenthesized_range(
|
||||
iter.into(),
|
||||
for_stmt.into(),
|
||||
checker.comment_ranges(),
|
||||
checker.source(),
|
||||
);
|
||||
|
||||
if let Some(range) = original_parenthesized_range {
|
||||
return locator.slice(range).to_string();
|
||||
}
|
||||
|
||||
let iter_in_source = locator.slice(iter);
|
||||
|
||||
match iter {
|
||||
Expr::Tuple(tuple) if !tuple.parenthesized => format!("({iter_in_source})"),
|
||||
_ => iter_in_source.to_string(),
|
||||
}
|
||||
}
|
||||
|
|
40
crates/ruff_linter/src/rules/refurb/rules/helpers.rs
Normal file
40
crates/ruff_linter/src/rules/refurb/rules/helpers.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use ruff_python_ast::{self as ast, parenthesize::parenthesized_range};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// A helper function that extracts the `iter` from a [`ast::StmtFor`] node and,
|
||||
/// if the `iter` is an unparenthesized tuple, adds parentheses:
|
||||
///
|
||||
/// - `for x in z: ...` -> `"x"`
|
||||
/// - `for (x, y) in z: ...` -> `"(x, y)"`
|
||||
/// - `for [x, y] in z: ...` -> `"[x, y]"`
|
||||
/// - `for x, y in z: ...` -> `"(x, y)"` # <-- Parentheses added only for this example
|
||||
pub(super) fn parenthesize_loop_iter_if_necessary<'a>(
|
||||
for_stmt: &'a ast::StmtFor,
|
||||
checker: &'a Checker,
|
||||
) -> Cow<'a, str> {
|
||||
let locator = checker.locator();
|
||||
let iter = for_stmt.iter.as_ref();
|
||||
|
||||
let original_parenthesized_range = parenthesized_range(
|
||||
iter.into(),
|
||||
for_stmt.into(),
|
||||
checker.comment_ranges(),
|
||||
checker.source(),
|
||||
);
|
||||
|
||||
if let Some(range) = original_parenthesized_range {
|
||||
return Cow::Borrowed(locator.slice(range));
|
||||
}
|
||||
|
||||
let iter_in_source = locator.slice(iter);
|
||||
|
||||
match iter {
|
||||
ast::Expr::Tuple(tuple) if !tuple.parenthesized => {
|
||||
Cow::Owned(format!("({iter_in_source})"))
|
||||
}
|
||||
_ => Cow::Borrowed(iter_in_source),
|
||||
}
|
||||
}
|
|
@ -42,6 +42,7 @@ mod for_loop_writes;
|
|||
mod fstring_number_format;
|
||||
mod hardcoded_string_charset;
|
||||
mod hashlib_digest_hex;
|
||||
mod helpers;
|
||||
mod if_exp_instead_of_or_operator;
|
||||
mod if_expr_min_max;
|
||||
mod implicit_cwd;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue