From 206d711be396ed59be2c6c3fc07ed0cadecaff59 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 3 Oct 2025 20:51:19 -0400 Subject: [PATCH] Mark unsafe --- .../rules/map_without_explicit_strict.rs | 19 +++++-------------- .../rules/zip_without_explicit_strict.rs | 19 +++++-------------- ...rules__flake8_bugbear__tests__B905.py.snap | 11 +++++++++++ ...bugbear__tests__preview__B912_B912.py.snap | 8 ++++++++ 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/map_without_explicit_strict.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/map_without_explicit_strict.rs index 49d60493743d87..13c6806433e7dd 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/map_without_explicit_strict.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/map_without_explicit_strict.rs @@ -34,9 +34,10 @@ use crate::{AlwaysFixableViolation, Applicability, Fix}; /// ``` /// /// ## Fix safety -/// This rule's fix is marked as unsafe for `map` calls that contain -/// `**kwargs`, as adding a `strict` keyword argument to such a call may lead -/// to a duplicate keyword argument error. +/// This rule's fix is marked as unsafe. While adding `strict=False` preserves +/// the runtime behavior, it can obscure situations where the iterables are of +/// unequal length. Ruff prefers to alert users so they can choose the intended +/// behavior themselves. /// /// ## References /// - [Python documentation: `map`](https://docs.python.org/3/library/functions.html#map) @@ -73,17 +74,7 @@ pub(crate) fn map_without_explicit_strict(checker: &Checker, call: &ast::ExprCal checker.comment_ranges(), checker.locator().contents(), ), - // If the function call contains `**kwargs`, mark the fix as unsafe. - if call - .arguments - .keywords - .iter() - .any(|keyword| keyword.arg.is_none()) - { - Applicability::Unsafe - } else { - Applicability::Safe - }, + Applicability::Unsafe, )); } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs index 9a4694491e6e9b..a432bbdce97e95 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs @@ -31,9 +31,10 @@ use crate::{AlwaysFixableViolation, Applicability, Fix}; /// ``` /// /// ## Fix safety -/// This rule's fix is marked as unsafe for `zip` calls that contain -/// `**kwargs`, as adding a `strict` keyword argument to such a call may lead -/// to a duplicate keyword argument error. +/// This rule's fix is marked as unsafe. While adding `strict=False` preserves +/// the runtime behavior, it can obscure situations where the iterables are of +/// unequal length. Ruff prefers to alert users so they can choose the intended +/// behavior themselves. /// /// ## References /// - [Python documentation: `zip`](https://docs.python.org/3/library/functions.html#zip) @@ -68,17 +69,7 @@ pub(crate) fn zip_without_explicit_strict(checker: &Checker, call: &ast::ExprCal checker.comment_ranges(), checker.locator().contents(), ), - // If the function call contains `**kwargs`, mark the fix as unsafe. - if call - .arguments - .keywords - .iter() - .any(|keyword| keyword.arg.is_none()) - { - Applicability::Unsafe - } else { - Applicability::Safe - }, + Applicability::Unsafe, )); } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B905.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B905.py.snap index 0682f5c5269070..8ea572c657dd8f 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B905.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B905.py.snap @@ -1,5 +1,6 @@ --- source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +assertion_line: 156 --- B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:4:1 @@ -19,6 +20,7 @@ help: Add explicit value for parameter `strict=` 5 | zip(range(3)) 6 | zip("a", "b") 7 | zip("a", "b", *zip("c")) +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:5:1 @@ -39,6 +41,7 @@ help: Add explicit value for parameter `strict=` 6 | zip("a", "b") 7 | zip("a", "b", *zip("c")) 8 | zip(zip("a"), strict=False) +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:6:1 @@ -59,6 +62,7 @@ help: Add explicit value for parameter `strict=` 7 | zip("a", "b", *zip("c")) 8 | zip(zip("a"), strict=False) 9 | zip(zip("a", strict=True)) +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:7:1 @@ -79,6 +83,7 @@ help: Add explicit value for parameter `strict=` 8 | zip(zip("a"), strict=False) 9 | zip(zip("a", strict=True)) 10 | +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:7:16 @@ -99,6 +104,7 @@ help: Add explicit value for parameter `strict=` 8 | zip(zip("a"), strict=False) 9 | zip(zip("a", strict=True)) 10 | +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:8:5 @@ -118,6 +124,7 @@ help: Add explicit value for parameter `strict=` 9 | zip(zip("a", strict=True)) 10 | 11 | # OK +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:9:1 @@ -138,6 +145,7 @@ help: Add explicit value for parameter `strict=` 10 | 11 | # OK 12 | zip(range(3), strict=True) +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:24:1 @@ -156,6 +164,7 @@ help: Add explicit value for parameter `strict=` 25 | zip([1, 2, 3], repeat(1, times=4)) 26 | 27 | import builtins +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:25:1 @@ -176,6 +185,7 @@ help: Add explicit value for parameter `strict=` 26 | 27 | import builtins 28 | # Still an error even though it uses the qualified name +note: This is an unsafe fix and may change runtime behavior B905 [*] `zip()` without an explicit `strict=` parameter --> B905.py:29:1 @@ -191,3 +201,4 @@ help: Add explicit value for parameter `strict=` 28 | # Still an error even though it uses the qualified name - builtins.zip([1, 2, 3]) 29 + builtins.zip([1, 2, 3], strict=False) +note: This is an unsafe fix and may change runtime behavior diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__preview__B912_B912.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__preview__B912_B912.py.snap index 102f1ce8ffdf6c..98a2147bbaf0f7 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__preview__B912_B912.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__preview__B912_B912.py.snap @@ -1,5 +1,6 @@ --- source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs +assertion_line: 112 --- B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:5:1 @@ -20,6 +21,7 @@ help: Add explicit value for parameter `strict=` 6 | map(lambda x, y, z: x + y + z, [1, 2, 3], [4, 5, 6], [7, 8, 9]) 7 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9])) 8 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]), strict=False) +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:6:1 @@ -40,6 +42,7 @@ help: Add explicit value for parameter `strict=` 7 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9])) 8 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]), strict=False) 9 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9], strict=True)) +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:7:1 @@ -61,6 +64,7 @@ help: Add explicit value for parameter `strict=` 9 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9], strict=True)) 10 | 11 | # Errors (limited iterators). +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:9:1 @@ -81,6 +85,7 @@ help: Add explicit value for parameter `strict=` 10 | 11 | # Errors (limited iterators). 12 | map(lambda x, y: x + y, [1, 2, 3], repeat(1, 1)) +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:12:1 @@ -99,6 +104,7 @@ help: Add explicit value for parameter `strict=` 13 | map(lambda x, y: x + y, [1, 2, 3], repeat(1, times=4)) 14 | 15 | import builtins +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:13:1 @@ -119,6 +125,7 @@ help: Add explicit value for parameter `strict=` 14 | 15 | import builtins 16 | # Still an error even though it uses the qualified name +note: This is an unsafe fix and may change runtime behavior B912 [*] `map()` without an explicit `strict=` parameter --> B912.py:17:1 @@ -139,3 +146,4 @@ help: Add explicit value for parameter `strict=` 18 | 19 | # OK 20 | map(lambda x: x, [1, 2, 3], strict=True) +note: This is an unsafe fix and may change runtime behavior