-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add b040: exception with note added not re-raised or used (#12097) #12764
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
196 changes: 196 additions & 0 deletions
196
crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B040.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
def arbitrary_fun(*args, **kwargs): ... | ||
|
||
|
||
def broken(): | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # error | ||
|
||
def not_broken(): | ||
try: | ||
... | ||
except Exception as e: # safe (other linters will catch this) | ||
pass | ||
|
||
def not_broken2(): | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") | ||
raise # safe | ||
|
||
def broken2(): | ||
# other exception raised | ||
try: | ||
... | ||
except Exception as e: | ||
f = ValueError() | ||
e.add_note("...") # error | ||
raise f | ||
|
||
def not_broken3(): | ||
# raised as cause | ||
try: | ||
... | ||
except Exception as e: | ||
f = ValueError() | ||
e.add_note("...") # safe | ||
raise f from e | ||
|
||
def not_broken4(): | ||
# assigned to other variable | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
foo = e | ||
|
||
def not_broken5(): | ||
# "used" in function call | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
# not that printing the exception is actually using it, but we treat | ||
# it being used as a parameter to any function as "using" it | ||
print(e) | ||
|
||
def not_broken6(): | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
list(e) | ||
|
||
def not_broken7(): | ||
# kwarg | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
arbitrary_fun(kwarg=e) | ||
|
||
def not_broken8(): | ||
# stararg | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
arbitrary_fun(*(e,)) | ||
|
||
def not_broken9(): | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("...") # safe | ||
arbitrary_fun(**{"e": e}) | ||
|
||
|
||
def broken3(): | ||
# multiple ExceptHandlers | ||
try: | ||
... | ||
except ValueError as e: | ||
e.add_note("") # error | ||
except TypeError as e: | ||
raise e | ||
|
||
def not_broken10(): | ||
# exception variable used before `add_note` | ||
mylist = [] | ||
try: | ||
... | ||
except Exception as e: # safe | ||
mylist.append(e) | ||
e.add_note("") | ||
|
||
def not_broken11(): | ||
# AnnAssign | ||
try: | ||
... | ||
except Exception as e: # safe | ||
e.add_note("") | ||
ann_assign_target: Exception = e | ||
|
||
def broken4(): | ||
# special case: e is only used in the `add_note` call itself | ||
try: | ||
... | ||
except Exception as e: # error | ||
e.add_note(str(e)) | ||
e.add_note(str(e)) | ||
|
||
def broken5(): | ||
# check nesting | ||
try: | ||
... | ||
except Exception as e: # error | ||
e.add_note("") | ||
try: | ||
... | ||
except ValueError as e: | ||
raise | ||
|
||
def broken6(): | ||
# questionable if this should error | ||
try: | ||
... | ||
except Exception as e: | ||
e.add_note("") | ||
e = ValueError() | ||
|
||
|
||
|
||
def broken7(): | ||
exc = ValueError() | ||
exc.add_note("") | ||
|
||
|
||
def not_broken12(exc: ValueError): | ||
exc.add_note("") | ||
|
||
|
||
|
||
def not_broken13(): | ||
e2 = ValueError() | ||
try: | ||
... | ||
except Exception as e: | ||
e2.add_note(str(e)) # safe | ||
raise e2 | ||
|
||
|
||
def broken8(): | ||
try: | ||
... | ||
except Exception as e: # should error | ||
e.add_note("") | ||
f = lambda e: e | ||
|
||
def broken9(): | ||
try: | ||
... | ||
except Exception as e: # should error | ||
e.add_note("") | ||
|
||
def habla(e): | ||
raise e | ||
|
||
|
||
# *** unhandled cases *** | ||
# We also don't track other variables | ||
try: | ||
... | ||
except Exception as e: | ||
e3 = e | ||
e3.add_note("") # should error | ||
|
||
# we currently only check the target of the except handler, even though this clearly | ||
# is hitting the same general pattern. But handling this case without a lot of false | ||
# alarms is very tricky without more infrastructure. | ||
try: | ||
... | ||
except Exception as e: | ||
e2 = ValueError() # should error | ||
e2.add_note(str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The rule name is very close to
SIM105
suppressible-exception
.Which makes me wonder if the rule should be integrated into
PLW0133
? @AlexWaygood what do you think?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 agree the name is similar, but this check is about checking if there is only
add_note
executed on the exception, so it's quite different from SIM105. On the other hand it is similar to PLW0133, but this rule exists in the flake8 bugbear, so it might be worth keeping the same set of rules with upstream..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.
Integrating it into
PLW0133
is appealing because it's a more general rule, and I agree that this is just trying to tackle a variant of that problem.But flake8-bugbear is more popular and widely used than pylint, I think, and I believe people much more often select our
B
rules than ourPLW
rules. So I agree that consistency with flake8-bugbear is useful here.I think that when doing rule recategorisation (a medium-term goal that you don't have to worry about here @divident), we'll probably no longer have categories that refer to older linters, and at that point it would probably make sense to merge
PLW0133
and this rule. But for now I guess I'd go for a separate check, despite how similar the two rules are.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.
It feels strange to me to introduce a new rule if we know we'll want to merge it eventually anyway. But I do see the point and redirects are relatively cheap for users.
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 I think we have to come up a more specific name to also make it clear that this is a very specific rule and it doesn't aim to catch all suppressed exceptions.
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.
What about the name "add_note_exception_suppression" ?
A few more suggestions: