Skip to content

Commit ac1c934

Browse files
committed
[tryceratops] - add fix for error-instead-of-exception (TRY400)
1 parent 6183b8e commit ac1c934

File tree

4 files changed

+213
-4
lines changed

4 files changed

+213
-4
lines changed

crates/ruff_linter/src/rules/tryceratops/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ mod tests {
1111
use test_case::test_case;
1212

1313
use crate::registry::Rule;
14+
use crate::settings::types::PreviewMode;
15+
use crate::settings::LinterSettings;
1416
use crate::test::test_path;
1517
use crate::{assert_messages, settings};
1618

@@ -33,4 +35,22 @@ mod tests {
3335
assert_messages!(snapshot, diagnostics);
3436
Ok(())
3537
}
38+
39+
#[test_case(Rule::ErrorInsteadOfException, Path::new("TRY400.py"))]
40+
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
41+
let snapshot = format!(
42+
"preview__{}_{}",
43+
rule_code.noqa_code(),
44+
path.to_string_lossy()
45+
);
46+
let diagnostics = test_path(
47+
Path::new("tryceratops").join(path).as_path(),
48+
&LinterSettings {
49+
preview: PreviewMode::Enabled,
50+
..LinterSettings::for_rule(rule_code)
51+
},
52+
)?;
53+
assert_messages!(snapshot, diagnostics);
54+
Ok(())
55+
}
3656
}

crates/ruff_linter/src/rules/tryceratops/rules/error_instead_of_exception.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use ruff_diagnostics::{Diagnostic, Violation};
1+
use ast::{Expr, ExprAttribute};
2+
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
23
use ruff_macros::{derive_message_formats, violation};
34
use ruff_python_ast::visitor::Visitor;
45
use ruff_python_ast::{self as ast, ExceptHandler};
@@ -48,10 +49,16 @@ use crate::rules::tryceratops::helpers::LoggerCandidateVisitor;
4849
pub struct ErrorInsteadOfException;
4950

5051
impl Violation for ErrorInsteadOfException {
52+
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
53+
5154
#[derive_message_formats]
5255
fn message(&self) -> String {
5356
format!("Use `logging.exception` instead of `logging.error`")
5457
}
58+
59+
fn fix_title(&self) -> Option<String> {
60+
Some(format!("Replace with `exception`"))
61+
}
5562
}
5663

5764
/// TRY400
@@ -67,9 +74,20 @@ pub(crate) fn error_instead_of_exception(checker: &mut Checker, handlers: &[Exce
6774
for (expr, logging_level) in calls {
6875
if matches!(logging_level, LoggingLevel::Error) {
6976
if exc_info(&expr.arguments, checker.semantic()).is_none() {
70-
checker
71-
.diagnostics
72-
.push(Diagnostic::new(ErrorInsteadOfException, expr.range()));
77+
let mut diagnostic = Diagnostic::new(ErrorInsteadOfException, expr.range());
78+
79+
if checker.settings.preview.is_enabled() {
80+
let Expr::Attribute(ExprAttribute { attr, .. }) = expr.func.as_ref() else {
81+
return;
82+
};
83+
84+
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
85+
"exception".to_string(),
86+
attr.range(),
87+
)));
88+
}
89+
90+
checker.diagnostics.push(diagnostic);
7391
}
7492
}
7593
}

crates/ruff_linter/src/rules/tryceratops/snapshots/ruff_linter__rules__tryceratops__tests__error-instead-of-exception_TRY400.py.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ TRY400.py:16:9: TRY400 Use `logging.exception` instead of `logging.error`
1010
17 |
1111
18 | if True:
1212
|
13+
= help: Replace with `exception`
1314

1415
TRY400.py:19:13: TRY400 Use `logging.exception` instead of `logging.error`
1516
|
1617
18 | if True:
1718
19 | logging.error("Context message here")
1819
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
1920
|
21+
= help: Replace with `exception`
2022

2123
TRY400.py:26:9: TRY400 Use `logging.exception` instead of `logging.error`
2224
|
@@ -27,13 +29,15 @@ TRY400.py:26:9: TRY400 Use `logging.exception` instead of `logging.error`
2729
27 |
2830
28 | if True:
2931
|
32+
= help: Replace with `exception`
3033

3134
TRY400.py:29:13: TRY400 Use `logging.exception` instead of `logging.error`
3235
|
3336
28 | if True:
3437
29 | logger.error("Context message here")
3538
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
3639
|
40+
= help: Replace with `exception`
3741

3842
TRY400.py:36:9: TRY400 Use `logging.exception` instead of `logging.error`
3943
|
@@ -44,13 +48,15 @@ TRY400.py:36:9: TRY400 Use `logging.exception` instead of `logging.error`
4448
37 |
4549
38 | if True:
4650
|
51+
= help: Replace with `exception`
4752

4853
TRY400.py:39:13: TRY400 Use `logging.exception` instead of `logging.error`
4954
|
5055
38 | if True:
5156
39 | log.error("Context message here")
5257
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
5358
|
59+
= help: Replace with `exception`
5460

5561
TRY400.py:46:9: TRY400 Use `logging.exception` instead of `logging.error`
5662
|
@@ -61,13 +67,15 @@ TRY400.py:46:9: TRY400 Use `logging.exception` instead of `logging.error`
6167
47 |
6268
48 | if True:
6369
|
70+
= help: Replace with `exception`
6471

6572
TRY400.py:49:13: TRY400 Use `logging.exception` instead of `logging.error`
6673
|
6774
48 | if True:
6875
49 | self.logger.error("Context message here")
6976
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
7077
|
78+
= help: Replace with `exception`
7179

7280
TRY400.py:87:9: TRY400 Use `logging.exception` instead of `logging.error`
7381
|
@@ -78,13 +86,15 @@ TRY400.py:87:9: TRY400 Use `logging.exception` instead of `logging.error`
7886
88 |
7987
89 | if True:
8088
|
89+
= help: Replace with `exception`
8190

8291
TRY400.py:90:13: TRY400 Use `logging.exception` instead of `logging.error`
8392
|
8493
89 | if True:
8594
90 | error("Context message here")
8695
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
8796
|
97+
= help: Replace with `exception`
8898

8999
TRY400.py:121:13: TRY400 Use `logging.exception` instead of `logging.error`
90100
|
@@ -93,5 +103,6 @@ TRY400.py:121:13: TRY400 Use `logging.exception` instead of `logging.error`
93103
121 | error("Context message here")
94104
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
95105
|
106+
= help: Replace with `exception`
96107

97108

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
source: crates/ruff_linter/src/rules/tryceratops/mod.rs
3+
---
4+
TRY400.py:16:9: TRY400 [*] Use `logging.exception` instead of `logging.error`
5+
|
6+
14 | a = 1
7+
15 | except Exception:
8+
16 | logging.error("Context message here")
9+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
10+
17 |
11+
18 | if True:
12+
|
13+
= help: Replace with `exception`
14+
15+
Safe fix
16+
13 13 | try:
17+
14 14 | a = 1
18+
15 15 | except Exception:
19+
16 |- logging.error("Context message here")
20+
16 |+ logging.exception("Context message here")
21+
17 17 |
22+
18 18 | if True:
23+
19 19 | logging.error("Context message here")
24+
25+
TRY400.py:19:13: TRY400 [*] Use `logging.exception` instead of `logging.error`
26+
|
27+
18 | if True:
28+
19 | logging.error("Context message here")
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
30+
|
31+
= help: Replace with `exception`
32+
33+
Safe fix
34+
16 16 | logging.error("Context message here")
35+
17 17 |
36+
18 18 | if True:
37+
19 |- logging.error("Context message here")
38+
19 |+ logging.exception("Context message here")
39+
20 20 |
40+
21 21 |
41+
22 22 | def bad():
42+
43+
TRY400.py:26:9: TRY400 [*] Use `logging.exception` instead of `logging.error`
44+
|
45+
24 | a = 1
46+
25 | except Exception:
47+
26 | logger.error("Context message here")
48+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
49+
27 |
50+
28 | if True:
51+
|
52+
= help: Replace with `exception`
53+
54+
Safe fix
55+
23 23 | try:
56+
24 24 | a = 1
57+
25 25 | except Exception:
58+
26 |- logger.error("Context message here")
59+
26 |+ logger.exception("Context message here")
60+
27 27 |
61+
28 28 | if True:
62+
29 29 | logger.error("Context message here")
63+
64+
TRY400.py:29:13: TRY400 [*] Use `logging.exception` instead of `logging.error`
65+
|
66+
28 | if True:
67+
29 | logger.error("Context message here")
68+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
69+
|
70+
= help: Replace with `exception`
71+
72+
Safe fix
73+
26 26 | logger.error("Context message here")
74+
27 27 |
75+
28 28 | if True:
76+
29 |- logger.error("Context message here")
77+
29 |+ logger.exception("Context message here")
78+
30 30 |
79+
31 31 |
80+
32 32 | def bad():
81+
82+
TRY400.py:36:9: TRY400 [*] Use `logging.exception` instead of `logging.error`
83+
|
84+
34 | a = 1
85+
35 | except Exception:
86+
36 | log.error("Context message here")
87+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
88+
37 |
89+
38 | if True:
90+
|
91+
= help: Replace with `exception`
92+
93+
Safe fix
94+
33 33 | try:
95+
34 34 | a = 1
96+
35 35 | except Exception:
97+
36 |- log.error("Context message here")
98+
36 |+ log.exception("Context message here")
99+
37 37 |
100+
38 38 | if True:
101+
39 39 | log.error("Context message here")
102+
103+
TRY400.py:39:13: TRY400 [*] Use `logging.exception` instead of `logging.error`
104+
|
105+
38 | if True:
106+
39 | log.error("Context message here")
107+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
108+
|
109+
= help: Replace with `exception`
110+
111+
Safe fix
112+
36 36 | log.error("Context message here")
113+
37 37 |
114+
38 38 | if True:
115+
39 |- log.error("Context message here")
116+
39 |+ log.exception("Context message here")
117+
40 40 |
118+
41 41 |
119+
42 42 | def bad():
120+
121+
TRY400.py:46:9: TRY400 [*] Use `logging.exception` instead of `logging.error`
122+
|
123+
44 | a = 1
124+
45 | except Exception:
125+
46 | self.logger.error("Context message here")
126+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
127+
47 |
128+
48 | if True:
129+
|
130+
= help: Replace with `exception`
131+
132+
Safe fix
133+
43 43 | try:
134+
44 44 | a = 1
135+
45 45 | except Exception:
136+
46 |- self.logger.error("Context message here")
137+
46 |+ self.logger.exception("Context message here")
138+
47 47 |
139+
48 48 | if True:
140+
49 49 | self.logger.error("Context message here")
141+
142+
TRY400.py:49:13: TRY400 [*] Use `logging.exception` instead of `logging.error`
143+
|
144+
48 | if True:
145+
49 | self.logger.error("Context message here")
146+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TRY400
147+
|
148+
= help: Replace with `exception`
149+
150+
Safe fix
151+
46 46 | self.logger.error("Context message here")
152+
47 47 |
153+
48 48 | if True:
154+
49 |- self.logger.error("Context message here")
155+
49 |+ self.logger.exception("Context message here")
156+
50 50 |
157+
51 51 |
158+
52 52 | def good():
159+
160+

0 commit comments

Comments
 (0)