From a4ded5941cfe4b65770b8608bdcf62c5a6f074bc Mon Sep 17 00:00:00 2001 From: chiri Date: Mon, 19 Jan 2026 21:00:55 +0300 Subject: [PATCH] [`flake8-bugbear`] Make fix unsafe if it deletes comments (`B010`) (#22657) ## Summary ## Test Plan --- .../src/rules/flake8_bugbear/rules/setattr_with_constant.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 51fee45110..6bcabe33fc 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -36,6 +36,9 @@ use crate::{AlwaysFixableViolation, Edit, Fix}; /// Rewriting `setattr(obj, "ſ", 1)` to `obj.ſ = 1` would be interpreted as `obj.s = 1` at /// runtime, changing behavior. /// +/// Additionally, the fix is marked as unsafe if the expression contains comments, +/// as the replacement may remove comments attached to the original `setattr` call. +/// /// For example, the long s character `"ſ"` normalizes to `"s"` under NFKC, so: /// ```python /// # This creates an attribute with the exact name "ſ" @@ -111,7 +114,8 @@ pub(crate) fn setattr_with_constant(checker: &Checker, expr: &Expr, func: &Expr, // attribute syntax (e.g., `obj.attr = value`) would normalize the name and potentially change // program behavior. let attr_name = name.to_str(); - let is_unsafe = attr_name.nfkc().collect::() != attr_name; + let has_comments = checker.comment_ranges().intersects(expr.range()); + let is_unsafe = attr_name.nfkc().collect::() != attr_name || has_comments; // We can only replace a `setattr` call (which is an `Expr`) with an assignment // (which is a `Stmt`) if the `Expr` is already being used as a `Stmt`