Skip to content

Commit 07b293d

Browse files
Add fix to automatically remove print and pprint statements (#9208)
Closes #9207.
1 parent 5ccc21a commit 07b293d

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

crates/ruff_linter/src/rules/flake8_print/rules/print_call.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use ruff_diagnostics::{Diagnostic, Violation};
1+
use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation};
22
use ruff_macros::{derive_message_formats, violation};
3-
4-
use ruff_python_ast::{self as ast};
3+
use ruff_python_ast as ast;
54
use ruff_text_size::Ranged;
65

76
use crate::checkers::ast::Checker;
7+
use crate::fix::edits::delete_stmt;
88
use crate::registry::AsRule;
99

1010
/// ## What it does
@@ -28,14 +28,24 @@ use crate::registry::AsRule;
2828
/// def add_numbers(a, b):
2929
/// return a + b
3030
/// ```
31+
///
32+
/// ## Fix safety
33+
/// This rule's fix is marked as unsafe, as it may remove `print` statements
34+
/// that are used beyond debugging purposes.
3135
#[violation]
3236
pub struct Print;
3337

3438
impl Violation for Print {
39+
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
40+
3541
#[derive_message_formats]
3642
fn message(&self) -> String {
3743
format!("`print` found")
3844
}
45+
46+
fn fix_title(&self) -> Option<String> {
47+
Some("Remove `print`".to_string())
48+
}
3949
}
4050

4151
/// ## What it does
@@ -65,19 +75,29 @@ impl Violation for Print {
6575
/// dict_c = {**dict_a, **dict_b}
6676
/// return dict_c
6777
/// ```
78+
///
79+
/// ## Fix safety
80+
/// This rule's fix is marked as unsafe, as it may remove `pprint` statements
81+
/// that are used beyond debugging purposes.
6882
#[violation]
6983
pub struct PPrint;
7084

7185
impl Violation for PPrint {
86+
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
87+
7288
#[derive_message_formats]
7389
fn message(&self) -> String {
7490
format!("`pprint` found")
7591
}
92+
93+
fn fix_title(&self) -> Option<String> {
94+
Some("Remove `pprint`".to_string())
95+
}
7696
}
7797

7898
/// T201, T203
7999
pub(crate) fn print_call(checker: &mut Checker, call: &ast::ExprCall) {
80-
let diagnostic = {
100+
let mut diagnostic = {
81101
let call_path = checker.semantic().resolve_call_path(&call.func);
82102
if call_path
83103
.as_ref()
@@ -113,5 +133,15 @@ pub(crate) fn print_call(checker: &mut Checker, call: &ast::ExprCall) {
113133
return;
114134
}
115135

136+
// Remove the `print`, if it's a standalone statement.
137+
if checker.semantic().current_expression_parent().is_none() {
138+
let statement = checker.semantic().current_statement();
139+
let parent = checker.semantic().current_statement_parent();
140+
let edit = delete_stmt(statement, parent, checker.locator(), checker.indexer());
141+
diagnostic.set_fix(Fix::unsafe_edit(edit).isolate(Checker::isolation(
142+
checker.semantic().current_statement_parent_id(),
143+
)));
144+
}
145+
116146
checker.diagnostics.push(diagnostic);
117147
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
source: crates/ruff_linter/src/rules/flake8_print/mod.rs
33
---
4-
T201.py:4:1: T201 `print` found
4+
T201.py:4:1: T201 [*] `print` found
55
|
66
2 | import tempfile
77
3 |
@@ -10,26 +10,56 @@ T201.py:4:1: T201 `print` found
1010
5 | print("Hello, world!", file=None) # T201
1111
6 | print("Hello, world!", file=sys.stdout) # T201
1212
|
13+
= help: Remove `print`
1314

14-
T201.py:5:1: T201 `print` found
15+
Unsafe fix
16+
1 1 | import sys
17+
2 2 | import tempfile
18+
3 3 |
19+
4 |-print("Hello, world!") # T201
20+
5 4 | print("Hello, world!", file=None) # T201
21+
6 5 | print("Hello, world!", file=sys.stdout) # T201
22+
7 6 | print("Hello, world!", file=sys.stderr) # T201
23+
24+
T201.py:5:1: T201 [*] `print` found
1525
|
1626
4 | print("Hello, world!") # T201
1727
5 | print("Hello, world!", file=None) # T201
1828
| ^^^^^ T201
1929
6 | print("Hello, world!", file=sys.stdout) # T201
2030
7 | print("Hello, world!", file=sys.stderr) # T201
2131
|
32+
= help: Remove `print`
33+
34+
Unsafe fix
35+
2 2 | import tempfile
36+
3 3 |
37+
4 4 | print("Hello, world!") # T201
38+
5 |-print("Hello, world!", file=None) # T201
39+
6 5 | print("Hello, world!", file=sys.stdout) # T201
40+
7 6 | print("Hello, world!", file=sys.stderr) # T201
41+
8 7 |
2242

23-
T201.py:6:1: T201 `print` found
43+
T201.py:6:1: T201 [*] `print` found
2444
|
2545
4 | print("Hello, world!") # T201
2646
5 | print("Hello, world!", file=None) # T201
2747
6 | print("Hello, world!", file=sys.stdout) # T201
2848
| ^^^^^ T201
2949
7 | print("Hello, world!", file=sys.stderr) # T201
3050
|
51+
= help: Remove `print`
3152

32-
T201.py:7:1: T201 `print` found
53+
Unsafe fix
54+
3 3 |
55+
4 4 | print("Hello, world!") # T201
56+
5 5 | print("Hello, world!", file=None) # T201
57+
6 |-print("Hello, world!", file=sys.stdout) # T201
58+
7 6 | print("Hello, world!", file=sys.stderr) # T201
59+
8 7 |
60+
9 8 | with tempfile.NamedTemporaryFile() as fp:
61+
62+
T201.py:7:1: T201 [*] `print` found
3363
|
3464
5 | print("Hello, world!", file=None) # T201
3565
6 | print("Hello, world!", file=sys.stdout) # T201
@@ -38,5 +68,15 @@ T201.py:7:1: T201 `print` found
3868
8 |
3969
9 | with tempfile.NamedTemporaryFile() as fp:
4070
|
71+
= help: Remove `print`
72+
73+
Unsafe fix
74+
4 4 | print("Hello, world!") # T201
75+
5 5 | print("Hello, world!", file=None) # T201
76+
6 6 | print("Hello, world!", file=sys.stdout) # T201
77+
7 |-print("Hello, world!", file=sys.stderr) # T201
78+
8 7 |
79+
9 8 | with tempfile.NamedTemporaryFile() as fp:
80+
10 9 | print("Hello, world!", file=fp) # OK
4181

4282

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
source: crates/ruff_linter/src/rules/flake8_print/mod.rs
33
---
4-
T203.py:3:1: T203 `pprint` found
4+
T203.py:3:1: T203 [*] `pprint` found
55
|
66
1 | from pprint import pprint
77
2 |
@@ -10,8 +10,17 @@ T203.py:3:1: T203 `pprint` found
1010
4 |
1111
5 | import pprint
1212
|
13+
= help: Remove `pprint`
1314

14-
T203.py:7:1: T203 `pprint` found
15+
Unsafe fix
16+
1 1 | from pprint import pprint
17+
2 2 |
18+
3 |-pprint("Hello, world!") # T203
19+
4 3 |
20+
5 4 | import pprint
21+
6 5 |
22+
23+
T203.py:7:1: T203 [*] `pprint` found
1524
|
1625
5 | import pprint
1726
6 |
@@ -20,5 +29,14 @@ T203.py:7:1: T203 `pprint` found
2029
8 |
2130
9 | pprint.pformat("Hello, world!")
2231
|
32+
= help: Remove `pprint`
33+
34+
Unsafe fix
35+
4 4 |
36+
5 5 | import pprint
37+
6 6 |
38+
7 |-pprint.pprint("Hello, world!") # T203
39+
8 7 |
40+
9 8 | pprint.pformat("Hello, world!")
2341

2442

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy