-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[flake8-simplify
] Preserve original behavior for except ()
and bare except
(SIM105
)
#18213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
SIM105 | 12 | 6 | 6 | 0 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+6 -6 violations, +0 -0 fixes in 2 projects; 53 projects unchanged)
apache/superset (+1 -1 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL
+ superset/migrations/versions/2015-12-04_09-42_1a48a5411020_adding_slug_to_dash.py:35:5: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - superset/migrations/versions/2015-12-04_09-42_1a48a5411020_adding_slug_to_dash.py:35:5: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass`
binary-husky/gpt_academic (+5 -5 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview
+ crazy_functions/Latex_Function.py:76:5: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - crazy_functions/Latex_Function.py:76:5: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass` + multi_language.py:363:9: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - multi_language.py:363:9: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass` + request_llms/com_qwenapi.py:57:21: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - request_llms/com_qwenapi.py:57:21: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass` + request_llms/oai_std_model_template.py:72:5: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - request_llms/oai_std_model_template.py:72:5: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass` + toolbox.py:463:13: SIM105 Use `contextlib.suppress(BaseException)` instead of `try`-`except`-`pass` - toolbox.py:463:13: SIM105 Use `contextlib.suppress(Exception)` instead of `try`-`except`-`pass`
Changes by rule (1 rules affected)
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
SIM105 | 12 | 6 | 6 | 0 | 0 |
"Exception".to_string() | ||
if type_.is_none() { | ||
// case where there are no handler names provided at all | ||
"BaseException".to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won’t work if BaseException
is shadowed. Here is an example of how to safely insert a builtin symbol:
ruff/crates/ruff_linter/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs
Lines 78 to 82 in b35bf8a
let (import_edit, binding) = checker.importer().get_or_import_builtin_symbol( | |
"callable", | |
expr.start(), | |
checker.semantic(), | |
)?; |
@ntBre I have a problem. How I could import more stuff at the same time? Do you have an example where it was made in another rule? I'm asking because here I would like to import |
Would this work ruff/crates/ruff_linter/src/rules/ruff/rules/quadratic_list_summation.rs Lines 105 to 115 in 9ae698f
|
Hey, I hope understood what you were asking ;-) |
format!("with {binding}({exception})"), | ||
let mut rest: Vec<Edit> = Vec::new(); | ||
let content: String; | ||
if exception == "BaseException" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this condition correct when BaseException
is shadowed and caught explicitly?
BaseException = ValueError
try:
int("a")
except BaseException:
pass
The fixed version should use suppress(BaseException)
, not suppress(builtins.BaseException)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. No, it was't. I added a new test case and fix that
It should be fine now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! The implementation looks reasonable to me, I just had a couple of vague ideas for your consideration.
I'm also kind of on the fence about whether we should offer the fix for the completely empty case. As mentioned in the issue, the fix could obscure a potential problem that would be caught by other lint rules.
I think the empty tuple case is okay because useless-contextlib-suppress (B022) will catch the empty suppress
, but I'm not seeing any diagnostics on contextlib.suppress(BaseException)
with all rules selected (playground).
If we still offer the fix, we could consider adding another rule similar to blind-except (BLE001) that applies to contextlib.suppress
(or extend one of these existing rules).
What do you think?
@@ -115,7 +118,13 @@ pub(crate) fn suppressible_exception( | |||
}; | |||
|
|||
let exception = if handler_names.is_empty() { | |||
"Exception".to_string() | |||
if type_.is_none() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could collapse this check like the one below to
if handler_names.is_empty() && type_.is_none() {
because join
on an empty Vec
should also give the empty string. Maybe that's getting too clever though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then we lose one else
or?
the complete snippet is
let exception = if handler_names.is_empty() {
if type_.is_none() {
// case where there are no handler names provided at all
"BaseException".to_string()
} else {
// case where handler names is an empty tuple
String::new()
}
} else {
handler_names.join(", ")
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly, I was suggesting this:
let exception = if handler_names.is_empty() && type_.is_none() {
"BaseException".to_string()
} else {
handler_names.join(", ")
};
That does drop the middle else
, but String::new()
and handler_names.join(", ")
are equivalent when handler_names
is empty, so it's safe to combine the two else
branches. However, I think this is evidence that your current code is more clear 😄
crates/ruff_linter/src/rules/flake8_simplify/rules/suppressible_exception.rs
Show resolved
Hide resolved
There's a somewhat related request for this in #4923, except it's for |
I don't have strong opinions :-) let me know which solution you like and I would change the code accordingly |
I'll have to think a bit more about this. I'm mostly working on the 0.12 release this week, but I'm putting this on my todo list for afterward! Thanks for following up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move ahead with the fix and open an issue to add or extend a rule to catch contextlib.suppress(BaseException)
.
I think that means all of the questions are resolved and this is good to go?
@ntBre Yes good to go ;-) |
flake8-simplify
] fix handlers corner cases (SIM105
)flake8-simplify
] Preserve original behavior for except ()
and bare except
(SIM105
)
The PR addresses issue #18209.