[ruff] Fix --statistics reporting for unsafe fixes (#16756)

Fixes #16751

## Summary

Previously, unsafe fixes were counted as "fixable" in
`Printer::write_statistics`, in contrast to the behaviour in
`Printer::write_once`. This changes the behaviour to align with
`write_once`, including them only if `--unsafe-fixes` is set.

We now also reuse `Printer::write_summary` to avoid duplicating the
logic for whether or not to report if there are hidden fixes.

## Test Plan

Existing tests modified to use an unsafe-fixable rule, and new ones
added to cover the case with `--unsafe-fixes`
This commit is contained in:
Peter Hill 2025-03-18 07:03:14 +00:00 committed by GitHub
parent b7d232cf89
commit 433879d852
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 12 deletions

View file

@ -353,7 +353,11 @@ impl Printer {
code: message.rule().map(std::convert::Into::into),
name: message.kind().into(),
count,
fixable: message.fixable(),
fixable: if let Some(fix) = message.fix() {
fix.applies(self.unsafe_fixes.required_applicability())
} else {
false
},
})
.sorted_by_key(|statistic| Reverse(statistic.count))
.collect();
@ -412,9 +416,7 @@ impl Printer {
)?;
}
if any_fixable {
writeln!(writer, "[*] fixable with `ruff check --fix`",)?;
}
self.write_summary_text(writer, diagnostics)?;
return Ok(());
}
OutputFormat::Json => {

View file

@ -950,15 +950,40 @@ fn rule_invalid_rule_name() {
#[test]
fn show_statistics() {
let mut cmd = RuffCheck::default()
.args(["--select", "F401", "--statistics"])
.args(["--select", "C416", "--statistics"])
.build();
assert_cmd_snapshot!(cmd
.pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r"
.pass_stdin(r#"
def mvce(keys, values):
return {key: value for key, value in zip(keys, values)}
"#), @r"
success: false
exit_code: 1
----- stdout -----
1 F401 [*] unused-import
[*] fixable with `ruff check --fix`
1 C416 unnecessary-comprehension
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
----- stderr -----
");
}
#[test]
fn show_statistics_unsafe_fixes() {
let mut cmd = RuffCheck::default()
.args(["--select", "C416", "--statistics", "--unsafe-fixes"])
.build();
assert_cmd_snapshot!(cmd
.pass_stdin(r#"
def mvce(keys, values):
return {key: value for key, value in zip(keys, values)}
"#), @r"
success: false
exit_code: 1
----- stdout -----
1 C416 [*] unnecessary-comprehension
Found 1 error.
[*] 1 fixable with the --fix option.
----- stderr -----
");
@ -969,21 +994,57 @@ fn show_statistics_json() {
let mut cmd = RuffCheck::default()
.args([
"--select",
"F401",
"C416",
"--statistics",
"--output-format",
"json",
])
.build();
assert_cmd_snapshot!(cmd
.pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r#"
.pass_stdin(r#"
def mvce(keys, values):
return {key: value for key, value in zip(keys, values)}
"#), @r#"
success: false
exit_code: 1
----- stdout -----
[
{
"code": "F401",
"name": "unused-import",
"code": "C416",
"name": "unnecessary-comprehension",
"count": 1,
"fixable": false
}
]
----- stderr -----
"#);
}
#[test]
fn show_statistics_json_unsafe_fixes() {
let mut cmd = RuffCheck::default()
.args([
"--select",
"C416",
"--statistics",
"--unsafe-fixes",
"--output-format",
"json",
])
.build();
assert_cmd_snapshot!(cmd
.pass_stdin(r#"
def mvce(keys, values):
return {key: value for key, value in zip(keys, values)}
"#), @r#"
success: false
exit_code: 1
----- stdout -----
[
{
"code": "C416",
"name": "unnecessary-comprehension",
"count": 1,
"fixable": true
}