mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Implement flake8-simplify SIM105 rule (#1621)
This commit is contained in:
parent
8b07f9517a
commit
0df28bdd4e
9 changed files with 137 additions and 8 deletions
|
@ -960,9 +960,10 @@ For more, see [flake8-simplify](https://pypi.org/project/flake8-simplify/0.19.3/
|
||||||
|
|
||||||
| Code | Name | Message | Fix |
|
| Code | Name | Message | Fix |
|
||||||
| ---- | ---- | ------- | --- |
|
| ---- | ---- | ------- | --- |
|
||||||
|
| SIM105 | UseContextlibSuppress | Use 'contextlib.suppress(..)' instead of try-except-pass | |
|
||||||
|
| SIM118 | KeyInDict | Use `key in dict` instead of `key in dict.keys()` | 🛠 |
|
||||||
| SIM220 | AAndNotA | Use `False` instead of `... and not ...` | 🛠 |
|
| SIM220 | AAndNotA | Use `False` instead of `... and not ...` | 🛠 |
|
||||||
| SIM221 | AOrNotA | Use `True` instead of `... or not ...` | 🛠 |
|
| SIM221 | AOrNotA | Use `True` instead of `... or not ...` | 🛠 |
|
||||||
| SIM118 | KeyInDict | Use `key in dict` instead of `key in dict.keys()` | 🛠 |
|
|
||||||
| SIM222 | OrTrue | Use `True` instead of `... or True` | 🛠 |
|
| SIM222 | OrTrue | Use `True` instead of `... or True` | 🛠 |
|
||||||
| SIM223 | AndFalse | Use `False` instead of `... and False` | 🛠 |
|
| SIM223 | AndFalse | Use `False` instead of `... and False` | 🛠 |
|
||||||
| SIM300 | YodaConditions | Use `left == right` instead of `right == left (Yoda-conditions)` | 🛠 |
|
| SIM300 | YodaConditions | Use `left == right` instead of `right == left (Yoda-conditions)` | 🛠 |
|
||||||
|
@ -1354,7 +1355,7 @@ natively, including:
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||||
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
||||||
- [`flake8-simplify`](https://pypi.org/project/flake8-simplify/) (6/30)
|
- [`flake8-simplify`](https://pypi.org/project/flake8-simplify/) (7/30)
|
||||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||||
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/)
|
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/)
|
||||||
- [`isort`](https://pypi.org/project/isort/)
|
- [`isort`](https://pypi.org/project/isort/)
|
||||||
|
@ -1412,7 +1413,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||||
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
||||||
- [`flake8-simplify`](https://pypi.org/project/flake8-simplify/) (6/30)
|
- [`flake8-simplify`](https://pypi.org/project/flake8-simplify/) (7/30)
|
||||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||||
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/)
|
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/)
|
||||||
- [`mccabe`](https://pypi.org/project/mccabe/)
|
- [`mccabe`](https://pypi.org/project/mccabe/)
|
||||||
|
|
31
resources/test/fixtures/flake8_simplify/SIM105.py
vendored
Normal file
31
resources/test/fixtures/flake8_simplify/SIM105.py
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
def foo():
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
foo()
|
||||||
|
except ValueError: # SIM105
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
foo()
|
||||||
|
except (ValueError, OSError): # SIM105
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
foo()
|
||||||
|
except: # SIM105
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
foo()
|
||||||
|
except ValueError:
|
||||||
|
print('foo')
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
foo()
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print('bar')
|
|
@ -1247,7 +1247,9 @@ where
|
||||||
flake8_simplify::plugins::key_in_dict_for(self, target, iter);
|
flake8_simplify::plugins::key_in_dict_for(self, target, iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Try { handlers, .. } => {
|
StmtKind::Try {
|
||||||
|
handlers, orelse, ..
|
||||||
|
} => {
|
||||||
if self.settings.enabled.contains(&CheckCode::F707) {
|
if self.settings.enabled.contains(&CheckCode::F707) {
|
||||||
if let Some(check) =
|
if let Some(check) =
|
||||||
pyflakes::checks::default_except_not_last(handlers, self.locator)
|
pyflakes::checks::default_except_not_last(handlers, self.locator)
|
||||||
|
@ -1272,6 +1274,9 @@ where
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if self.settings.enabled.contains(&CheckCode::SIM105) {
|
||||||
|
flake8_simplify::plugins::use_contextlib_suppress(self, stmt, handlers, orelse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Assign { targets, value, .. } => {
|
StmtKind::Assign { targets, value, .. } => {
|
||||||
if self.settings.enabled.contains(&CheckCode::E731) {
|
if self.settings.enabled.contains(&CheckCode::E731) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ mod tests {
|
||||||
use crate::registry::CheckCode;
|
use crate::registry::CheckCode;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
|
#[test_case(CheckCode::SIM105, Path::new("SIM105.py"); "SIM105")]
|
||||||
#[test_case(CheckCode::SIM118, Path::new("SIM118.py"); "SIM118")]
|
#[test_case(CheckCode::SIM118, Path::new("SIM118.py"); "SIM118")]
|
||||||
#[test_case(CheckCode::SIM222, Path::new("SIM222.py"); "SIM222")]
|
#[test_case(CheckCode::SIM222, Path::new("SIM222.py"); "SIM222")]
|
||||||
#[test_case(CheckCode::SIM223, Path::new("SIM223.py"); "SIM223")]
|
#[test_case(CheckCode::SIM223, Path::new("SIM223.py"); "SIM223")]
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
pub use bool_ops::{a_and_not_a, a_or_not_a, and_false, or_true};
|
pub use bool_ops::{a_and_not_a, a_or_not_a, and_false, or_true};
|
||||||
pub use key_in_dict::{key_in_dict_compare, key_in_dict_for};
|
pub use key_in_dict::{key_in_dict_compare, key_in_dict_for};
|
||||||
|
pub use use_contextlib_suppress::use_contextlib_suppress;
|
||||||
pub use yoda_conditions::yoda_conditions;
|
pub use yoda_conditions::yoda_conditions;
|
||||||
|
|
||||||
mod bool_ops;
|
mod bool_ops;
|
||||||
mod key_in_dict;
|
mod key_in_dict;
|
||||||
|
mod use_contextlib_suppress;
|
||||||
mod yoda_conditions;
|
mod yoda_conditions;
|
||||||
|
|
38
src/flake8_simplify/plugins/use_contextlib_suppress.rs
Normal file
38
src/flake8_simplify/plugins/use_contextlib_suppress.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Stmt, StmtKind};
|
||||||
|
|
||||||
|
use crate::ast::helpers;
|
||||||
|
use crate::ast::types::Range;
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::registry::{Check, CheckKind};
|
||||||
|
|
||||||
|
/// SIM105
|
||||||
|
pub fn use_contextlib_suppress(
|
||||||
|
checker: &mut Checker,
|
||||||
|
stmt: &Stmt,
|
||||||
|
handlers: &[Excepthandler],
|
||||||
|
orelse: &[Stmt],
|
||||||
|
) {
|
||||||
|
if handlers.len() != 1 || !orelse.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let handler = &handlers[0];
|
||||||
|
let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node;
|
||||||
|
if body.len() == 1 {
|
||||||
|
if matches!(body[0].node, StmtKind::Pass) {
|
||||||
|
let handler_names: Vec<_> = helpers::extract_handler_names(handlers)
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
let exception = if handler_names.is_empty() {
|
||||||
|
"Exception".to_string()
|
||||||
|
} else {
|
||||||
|
handler_names.join(", ")
|
||||||
|
};
|
||||||
|
let check = Check::new(
|
||||||
|
CheckKind::UseContextlibSuppress(exception),
|
||||||
|
Range::from_located(stmt),
|
||||||
|
);
|
||||||
|
checker.add_check(check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
source: src/flake8_simplify/mod.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
UseContextlibSuppress: ValueError
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 7
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
UseContextlibSuppress: "ValueError, OSError"
|
||||||
|
location:
|
||||||
|
row: 9
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 12
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
UseContextlibSuppress: Exception
|
||||||
|
location:
|
||||||
|
row: 14
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 17
|
||||||
|
column: 8
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
|
|
@ -217,9 +217,10 @@ pub enum CheckCode {
|
||||||
YTT302,
|
YTT302,
|
||||||
YTT303,
|
YTT303,
|
||||||
// flake8-simplify
|
// flake8-simplify
|
||||||
|
SIM105,
|
||||||
|
SIM118,
|
||||||
SIM220,
|
SIM220,
|
||||||
SIM221,
|
SIM221,
|
||||||
SIM118,
|
|
||||||
SIM222,
|
SIM222,
|
||||||
SIM223,
|
SIM223,
|
||||||
SIM300,
|
SIM300,
|
||||||
|
@ -876,6 +877,7 @@ pub enum CheckKind {
|
||||||
UnaryPrefixIncrement,
|
UnaryPrefixIncrement,
|
||||||
UnreliableCallableCheck,
|
UnreliableCallableCheck,
|
||||||
UnusedLoopControlVariable(String),
|
UnusedLoopControlVariable(String),
|
||||||
|
UseContextlibSuppress(String),
|
||||||
UselessComparison,
|
UselessComparison,
|
||||||
UselessContextlibSuppress,
|
UselessContextlibSuppress,
|
||||||
UselessExpression,
|
UselessExpression,
|
||||||
|
@ -1377,6 +1379,7 @@ impl CheckCode {
|
||||||
// flake8-blind-except
|
// flake8-blind-except
|
||||||
CheckCode::BLE001 => CheckKind::BlindExcept("Exception".to_string()),
|
CheckCode::BLE001 => CheckKind::BlindExcept("Exception".to_string()),
|
||||||
// flake8-simplify
|
// flake8-simplify
|
||||||
|
CheckCode::SIM105 => CheckKind::UseContextlibSuppress("..".to_string()),
|
||||||
CheckCode::SIM118 => CheckKind::KeyInDict("key".to_string(), "dict".to_string()),
|
CheckCode::SIM118 => CheckKind::KeyInDict("key".to_string(), "dict".to_string()),
|
||||||
CheckCode::SIM220 => CheckKind::AAndNotA("...".to_string()),
|
CheckCode::SIM220 => CheckKind::AAndNotA("...".to_string()),
|
||||||
CheckCode::SIM221 => CheckKind::AOrNotA("...".to_string()),
|
CheckCode::SIM221 => CheckKind::AOrNotA("...".to_string()),
|
||||||
|
@ -1903,6 +1906,7 @@ impl CheckCode {
|
||||||
CheckCode::S106 => CheckCategory::Flake8Bandit,
|
CheckCode::S106 => CheckCategory::Flake8Bandit,
|
||||||
CheckCode::S107 => CheckCategory::Flake8Bandit,
|
CheckCode::S107 => CheckCategory::Flake8Bandit,
|
||||||
// flake8-simplify
|
// flake8-simplify
|
||||||
|
CheckCode::SIM105 => CheckCategory::Flake8Simplify,
|
||||||
CheckCode::SIM118 => CheckCategory::Flake8Simplify,
|
CheckCode::SIM118 => CheckCategory::Flake8Simplify,
|
||||||
CheckCode::SIM220 => CheckCategory::Flake8Simplify,
|
CheckCode::SIM220 => CheckCategory::Flake8Simplify,
|
||||||
CheckCode::SIM221 => CheckCategory::Flake8Simplify,
|
CheckCode::SIM221 => CheckCategory::Flake8Simplify,
|
||||||
|
@ -2154,6 +2158,7 @@ impl CheckKind {
|
||||||
CheckKind::SysVersionCmpStr10 => &CheckCode::YTT302,
|
CheckKind::SysVersionCmpStr10 => &CheckCode::YTT302,
|
||||||
CheckKind::SysVersionSlice1Referenced => &CheckCode::YTT303,
|
CheckKind::SysVersionSlice1Referenced => &CheckCode::YTT303,
|
||||||
// flake8-simplify
|
// flake8-simplify
|
||||||
|
CheckKind::UseContextlibSuppress(..) => &CheckCode::SIM105,
|
||||||
CheckKind::KeyInDict(..) => &CheckCode::SIM118,
|
CheckKind::KeyInDict(..) => &CheckCode::SIM118,
|
||||||
CheckKind::AAndNotA(..) => &CheckCode::SIM220,
|
CheckKind::AAndNotA(..) => &CheckCode::SIM220,
|
||||||
CheckKind::AOrNotA(..) => &CheckCode::SIM221,
|
CheckKind::AOrNotA(..) => &CheckCode::SIM221,
|
||||||
|
@ -2667,6 +2672,9 @@ impl CheckKind {
|
||||||
CheckKind::FStringDocstring => "f-string used as docstring. This will be interpreted \
|
CheckKind::FStringDocstring => "f-string used as docstring. This will be interpreted \
|
||||||
by python as a joined string rather than a docstring."
|
by python as a joined string rather than a docstring."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
CheckKind::UseContextlibSuppress(exception) => {
|
||||||
|
format!("Use 'contextlib.suppress({exception})' instead of try-except-pass")
|
||||||
|
}
|
||||||
CheckKind::UselessContextlibSuppress => {
|
CheckKind::UselessContextlibSuppress => {
|
||||||
"No arguments passed to `contextlib.suppress`. No exceptions will be suppressed \
|
"No arguments passed to `contextlib.suppress`. No exceptions will be suppressed \
|
||||||
and therefore this context manager is redundant"
|
and therefore this context manager is redundant"
|
||||||
|
|
|
@ -515,6 +515,8 @@ pub enum CheckCodePrefix {
|
||||||
S107,
|
S107,
|
||||||
SIM,
|
SIM,
|
||||||
SIM1,
|
SIM1,
|
||||||
|
SIM10,
|
||||||
|
SIM105,
|
||||||
SIM11,
|
SIM11,
|
||||||
SIM118,
|
SIM118,
|
||||||
SIM2,
|
SIM2,
|
||||||
|
@ -801,9 +803,10 @@ impl CheckCodePrefix {
|
||||||
CheckCode::YTT301,
|
CheckCode::YTT301,
|
||||||
CheckCode::YTT302,
|
CheckCode::YTT302,
|
||||||
CheckCode::YTT303,
|
CheckCode::YTT303,
|
||||||
|
CheckCode::SIM105,
|
||||||
|
CheckCode::SIM118,
|
||||||
CheckCode::SIM220,
|
CheckCode::SIM220,
|
||||||
CheckCode::SIM221,
|
CheckCode::SIM221,
|
||||||
CheckCode::SIM118,
|
|
||||||
CheckCode::SIM222,
|
CheckCode::SIM222,
|
||||||
CheckCode::SIM223,
|
CheckCode::SIM223,
|
||||||
CheckCode::SIM300,
|
CheckCode::SIM300,
|
||||||
|
@ -2612,14 +2615,17 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::S106 => vec![CheckCode::S106],
|
CheckCodePrefix::S106 => vec![CheckCode::S106],
|
||||||
CheckCodePrefix::S107 => vec![CheckCode::S107],
|
CheckCodePrefix::S107 => vec![CheckCode::S107],
|
||||||
CheckCodePrefix::SIM => vec![
|
CheckCodePrefix::SIM => vec![
|
||||||
|
CheckCode::SIM105,
|
||||||
|
CheckCode::SIM118,
|
||||||
CheckCode::SIM220,
|
CheckCode::SIM220,
|
||||||
CheckCode::SIM221,
|
CheckCode::SIM221,
|
||||||
CheckCode::SIM118,
|
|
||||||
CheckCode::SIM222,
|
CheckCode::SIM222,
|
||||||
CheckCode::SIM223,
|
CheckCode::SIM223,
|
||||||
CheckCode::SIM300,
|
CheckCode::SIM300,
|
||||||
],
|
],
|
||||||
CheckCodePrefix::SIM1 => vec![CheckCode::SIM118],
|
CheckCodePrefix::SIM1 => vec![CheckCode::SIM105, CheckCode::SIM118],
|
||||||
|
CheckCodePrefix::SIM10 => vec![CheckCode::SIM105],
|
||||||
|
CheckCodePrefix::SIM105 => vec![CheckCode::SIM105],
|
||||||
CheckCodePrefix::SIM11 => vec![CheckCode::SIM118],
|
CheckCodePrefix::SIM11 => vec![CheckCode::SIM118],
|
||||||
CheckCodePrefix::SIM118 => vec![CheckCode::SIM118],
|
CheckCodePrefix::SIM118 => vec![CheckCode::SIM118],
|
||||||
CheckCodePrefix::SIM2 => vec![
|
CheckCodePrefix::SIM2 => vec![
|
||||||
|
@ -3583,6 +3589,8 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::S107 => SuffixLength::Three,
|
CheckCodePrefix::S107 => SuffixLength::Three,
|
||||||
CheckCodePrefix::SIM => SuffixLength::Zero,
|
CheckCodePrefix::SIM => SuffixLength::Zero,
|
||||||
CheckCodePrefix::SIM1 => SuffixLength::One,
|
CheckCodePrefix::SIM1 => SuffixLength::One,
|
||||||
|
CheckCodePrefix::SIM10 => SuffixLength::Two,
|
||||||
|
CheckCodePrefix::SIM105 => SuffixLength::Three,
|
||||||
CheckCodePrefix::SIM11 => SuffixLength::Two,
|
CheckCodePrefix::SIM11 => SuffixLength::Two,
|
||||||
CheckCodePrefix::SIM118 => SuffixLength::Three,
|
CheckCodePrefix::SIM118 => SuffixLength::Three,
|
||||||
CheckCodePrefix::SIM2 => SuffixLength::One,
|
CheckCodePrefix::SIM2 => SuffixLength::One,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue