mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[flake8-simplify
] Add autofix for contextlib.suppress
(SIM105
) (#3915)
This commit is contained in:
parent
311ba29d0f
commit
002caadf9e
2 changed files with 143 additions and 25 deletions
|
@ -1,36 +1,44 @@
|
||||||
use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Located, Stmt, StmtKind};
|
use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Located, Location, Stmt, StmtKind};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::call_path::compose_call_path;
|
use ruff_python_ast::call_path::compose_call_path;
|
||||||
use ruff_python_ast::helpers;
|
use ruff_python_ast::helpers;
|
||||||
use ruff_python_ast::types::Range;
|
use ruff_python_ast::types::Range;
|
||||||
|
|
||||||
|
use crate::autofix::actions::get_or_import_symbol;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::registry::AsRule;
|
||||||
|
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct SuppressibleException {
|
pub struct SuppressibleException {
|
||||||
pub exception: String,
|
pub exception: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Violation for SuppressibleException {
|
impl AlwaysAutofixableViolation for SuppressibleException {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let SuppressibleException { exception } = self;
|
let SuppressibleException { exception } = self;
|
||||||
format!("Use `contextlib.suppress({exception})` instead of try-except-pass")
|
format!("Use `contextlib.suppress({exception})` instead of `try`-`except`-`pass`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let SuppressibleException { exception } = self;
|
||||||
|
format!("Replace with `contextlib.suppress({exception})`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SIM105
|
/// SIM105
|
||||||
pub fn suppressible_exception(
|
pub fn suppressible_exception(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
body: &[Stmt],
|
try_body: &[Stmt],
|
||||||
handlers: &[Excepthandler],
|
handlers: &[Excepthandler],
|
||||||
orelse: &[Stmt],
|
orelse: &[Stmt],
|
||||||
finalbody: &[Stmt],
|
finalbody: &[Stmt],
|
||||||
) {
|
) {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
body,
|
try_body,
|
||||||
[Located {
|
[Located {
|
||||||
node: StmtKind::Delete { .. }
|
node: StmtKind::Delete { .. }
|
||||||
| StmtKind::Assign { .. }
|
| StmtKind::Assign { .. }
|
||||||
|
@ -62,10 +70,36 @@ pub fn suppressible_exception(
|
||||||
} else {
|
} else {
|
||||||
handler_names.join(", ")
|
handler_names.join(", ")
|
||||||
};
|
};
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
SuppressibleException { exception },
|
SuppressibleException {
|
||||||
|
exception: exception.clone(),
|
||||||
|
},
|
||||||
Range::from(stmt),
|
Range::from(stmt),
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
|
diagnostic.try_set_fix(|| {
|
||||||
|
let (import_edit, binding) = get_or_import_symbol(
|
||||||
|
"contextlib",
|
||||||
|
"suppress",
|
||||||
|
&checker.ctx,
|
||||||
|
&checker.importer,
|
||||||
|
checker.locator,
|
||||||
|
)?;
|
||||||
|
let try_ending = stmt.location.with_col_offset(3); // size of "try"
|
||||||
|
let replace_try = Edit::replacement(
|
||||||
|
format!("with {binding}({exception})"),
|
||||||
|
stmt.location,
|
||||||
|
try_ending,
|
||||||
|
);
|
||||||
|
let handler_line_begin = Location::new(handler.location.row(), 0);
|
||||||
|
let remove_handler =
|
||||||
|
Edit::deletion(handler_line_begin, handler.end_location.unwrap());
|
||||||
|
Ok(Fix::from_iter([import_edit, replace_try, remove_handler]))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ expression: diagnostics
|
||||||
---
|
---
|
||||||
- kind:
|
- kind:
|
||||||
name: SuppressibleException
|
name: SuppressibleException
|
||||||
body: "Use `contextlib.suppress(ValueError)` instead of try-except-pass"
|
body: "Use `contextlib.suppress(ValueError)` instead of `try`-`except`-`pass`"
|
||||||
suggestion: ~
|
suggestion: "Replace with `contextlib.suppress(ValueError)`"
|
||||||
fixable: false
|
fixable: true
|
||||||
location:
|
location:
|
||||||
row: 4
|
row: 4
|
||||||
column: 0
|
column: 0
|
||||||
|
@ -14,13 +14,34 @@ expression: diagnostics
|
||||||
row: 7
|
row: 7
|
||||||
column: 8
|
column: 8
|
||||||
fix:
|
fix:
|
||||||
edits: []
|
edits:
|
||||||
|
- content: "import contextlib\n"
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
- content: with contextlib.suppress(ValueError)
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 3
|
||||||
|
- content: ""
|
||||||
|
location:
|
||||||
|
row: 6
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 7
|
||||||
|
column: 8
|
||||||
parent: ~
|
parent: ~
|
||||||
- kind:
|
- kind:
|
||||||
name: SuppressibleException
|
name: SuppressibleException
|
||||||
body: "Use `contextlib.suppress(ValueError, OSError)` instead of try-except-pass"
|
body: "Use `contextlib.suppress(ValueError, OSError)` instead of `try`-`except`-`pass`"
|
||||||
suggestion: ~
|
suggestion: "Replace with `contextlib.suppress(ValueError, OSError)`"
|
||||||
fixable: false
|
fixable: true
|
||||||
location:
|
location:
|
||||||
row: 9
|
row: 9
|
||||||
column: 0
|
column: 0
|
||||||
|
@ -28,13 +49,34 @@ expression: diagnostics
|
||||||
row: 12
|
row: 12
|
||||||
column: 8
|
column: 8
|
||||||
fix:
|
fix:
|
||||||
edits: []
|
edits:
|
||||||
|
- content: "import contextlib\n"
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
- content: "with contextlib.suppress(ValueError, OSError)"
|
||||||
|
location:
|
||||||
|
row: 9
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 9
|
||||||
|
column: 3
|
||||||
|
- content: ""
|
||||||
|
location:
|
||||||
|
row: 11
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 12
|
||||||
|
column: 8
|
||||||
parent: ~
|
parent: ~
|
||||||
- kind:
|
- kind:
|
||||||
name: SuppressibleException
|
name: SuppressibleException
|
||||||
body: "Use `contextlib.suppress(Exception)` instead of try-except-pass"
|
body: "Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass`"
|
||||||
suggestion: ~
|
suggestion: "Replace with `contextlib.suppress(Exception)`"
|
||||||
fixable: false
|
fixable: true
|
||||||
location:
|
location:
|
||||||
row: 14
|
row: 14
|
||||||
column: 0
|
column: 0
|
||||||
|
@ -42,13 +84,34 @@ expression: diagnostics
|
||||||
row: 17
|
row: 17
|
||||||
column: 8
|
column: 8
|
||||||
fix:
|
fix:
|
||||||
edits: []
|
edits:
|
||||||
|
- content: "import contextlib\n"
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
- content: with contextlib.suppress(Exception)
|
||||||
|
location:
|
||||||
|
row: 14
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 14
|
||||||
|
column: 3
|
||||||
|
- content: ""
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 17
|
||||||
|
column: 8
|
||||||
parent: ~
|
parent: ~
|
||||||
- kind:
|
- kind:
|
||||||
name: SuppressibleException
|
name: SuppressibleException
|
||||||
body: "Use `contextlib.suppress(a.Error, b.Error)` instead of try-except-pass"
|
body: "Use `contextlib.suppress(a.Error, b.Error)` instead of `try`-`except`-`pass`"
|
||||||
suggestion: ~
|
suggestion: "Replace with `contextlib.suppress(a.Error, b.Error)`"
|
||||||
fixable: false
|
fixable: true
|
||||||
location:
|
location:
|
||||||
row: 19
|
row: 19
|
||||||
column: 0
|
column: 0
|
||||||
|
@ -56,6 +119,27 @@ expression: diagnostics
|
||||||
row: 22
|
row: 22
|
||||||
column: 8
|
column: 8
|
||||||
fix:
|
fix:
|
||||||
edits: []
|
edits:
|
||||||
|
- content: "import contextlib\n"
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
- content: "with contextlib.suppress(a.Error, b.Error)"
|
||||||
|
location:
|
||||||
|
row: 19
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 19
|
||||||
|
column: 3
|
||||||
|
- content: ""
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 22
|
||||||
|
column: 8
|
||||||
parent: ~
|
parent: ~
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue