mirror of
https://github.com/astral-sh/ruff
synced 2026-01-20 21:10:48 -05:00
Account for selector specificity when merging extend_unsafe_fixes and override extend_safe_fixes (#8444)
## Summary Prior to this change `extend_unsafe_fixes` took precedence over `extend_safe_fixes` selectors, so any conflicts were resolved in favour of `extend_unsafe_fixes`. Thanks to that ruff were conservatively assuming that if configs conlict the fix corresponding to selected rule will be treated as unsafe. After this change we take into account Specificity of the selectors. For conflicts between selectors of the same Specificity we will treat the corresponding fixes as unsafe. But if the conflicting selectors are of different specificity the more specific one will win. ## Test Plan Tests were added for the `FixSafetyTable` struct. The `check_extend_unsafe_fixes_conflict_with_extend_safe_fixes_by_specificity` integration test was added to test conflicting rules of different specificity. Fixes #8404 --------- Co-authored-by: Zanie <contact@zanie.dev>
This commit is contained in:
committed by
GitHub
parent
7873ca38e5
commit
03303a9edd
@@ -1407,3 +1407,47 @@ extend-safe-fixes = ["UP034"]
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_extend_unsafe_fixes_conflict_with_extend_safe_fixes_by_specificity() -> Result<()> {
|
||||
// Adding a rule to one option with a more specific selector should override the other option
|
||||
let tempdir = TempDir::new()?;
|
||||
let ruff_toml = tempdir.path().join("ruff.toml");
|
||||
fs::write(
|
||||
&ruff_toml,
|
||||
r#"
|
||||
target-version = "py310"
|
||||
[lint]
|
||||
extend-unsafe-fixes = ["UP", "UP034"]
|
||||
extend-safe-fixes = ["UP03"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.args(["check", "--config"])
|
||||
.arg(&ruff_toml)
|
||||
.arg("-")
|
||||
.args([
|
||||
"--output-format",
|
||||
"text",
|
||||
"--no-cache",
|
||||
"--select",
|
||||
"F601,UP018,UP034,UP038",
|
||||
])
|
||||
.pass_stdin("x = {'a': 1, 'a': 1}\nprint(('foo'))\nprint(str('foo'))\nisinstance(x, (int, str))\n"),
|
||||
@r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:14: F601 Dictionary key literal `'a'` repeated
|
||||
-:2:7: UP034 Avoid extraneous parentheses
|
||||
-:3:7: UP018 Unnecessary `str` call (rewrite as a literal)
|
||||
-:4:1: UP038 [*] Use `X | Y` in `isinstance` call instead of `(X, Y)`
|
||||
Found 4 errors.
|
||||
[*] 1 fixable with the `--fix` option (3 hidden fixes can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user