[flake8-comprehension] Mark autofix for C420 as unsafe if there's comments inside the dict comprehension (#18768)

This commit is contained in:
Victor Hugo Gomes 2025-06-19 06:43:05 -03:00 committed by GitHub
parent 06da2c808f
commit 65b288b45b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 66 additions and 2 deletions

View file

@ -90,3 +90,14 @@ def func():
def func():
{(a, b): a + b for (a, b) in [(1, 2), (3, 4)]} # OK
# https://github.com/astral-sh/ruff/issues/18764
{ # 1
a # 2
: # 3
None # 4
for # 5
a # 6
in # 7
iterable # 8
} # 9

View file

@ -1,4 +1,5 @@
use ast::ExprName;
use ruff_diagnostics::Applicability;
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::comparable::ComparableExpr;
use ruff_python_ast::helpers::any_over_expr;
@ -31,6 +32,19 @@ use crate::{Edit, Fix, FixAvailability, Violation};
/// dict.fromkeys(iterable, 1)
/// ```
///
/// ## Fix safety
/// This rule's fix is marked as unsafe if there's comments inside the dict comprehension,
/// as comments may be removed.
///
/// For example, the fix would be marked as unsafe in the following case:
/// ```python
/// { # comment 1
/// a: # comment 2
/// None # comment 3
/// for a in iterable # comment 4
/// }
/// ```
///
/// ## References
/// - [Python documentation: `dict.fromkeys`](https://docs.python.org/3/library/stdtypes.html#dict.fromkeys)
#[derive(ViolationMetadata)]
@ -121,7 +135,7 @@ pub(crate) fn unnecessary_dict_comprehension_for_iterable(
);
if checker.semantic().has_builtin_binding("dict") {
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
let edit = Edit::range_replacement(
checker
.generator()
.expr(&fix_unnecessary_dict_comprehension(
@ -129,7 +143,15 @@ pub(crate) fn unnecessary_dict_comprehension_for_iterable(
generator,
)),
dict_comp.range(),
)));
);
diagnostic.set_fix(Fix::applicable_edit(
edit,
if checker.comment_ranges().intersects(dict_comp.range()) {
Applicability::Unsafe
} else {
Applicability::Safe
},
));
}
}

View file

@ -202,3 +202,34 @@ C420.py:59:6: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fr
60 60 |
61 61 |
62 62 | # Non-violation cases: RUF025
C420.py:95:1: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead
|
94 | # https://github.com/astral-sh/ruff/issues/18764
95 | / { # 1
96 | | a # 2
97 | | : # 3
98 | | None # 4
99 | | for # 5
100 | | a # 6
101 | | in # 7
102 | | iterable # 8
103 | | } # 9
| |_^ C420
|
= help: Replace with `dict.fromkeys(iterable, value)`)
Unsafe fix
92 92 | {(a, b): a + b for (a, b) in [(1, 2), (3, 4)]} # OK
93 93 |
94 94 | # https://github.com/astral-sh/ruff/issues/18764
95 |-{ # 1
96 |-a # 2
97 |-: # 3
98 |-None # 4
99 |-for # 5
100 |-a # 6
101 |-in # 7
102 |-iterable # 8
103 |-} # 9
95 |+dict.fromkeys(iterable) # 9