-
Notifications
You must be signed in to change notification settings - Fork 107
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 reraised or used #477
Conversation
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!
In regards to the questions:
- Agree, don't think it's worth it - especially with false positives
- I think since it's in an
except
clause something should be done with the exception there .,.. so it's a bug we should care about. Up to you how far you want to go in regards to lambdas and other
- Happy to start catching the blatant bugs - But let's note possible enhancements in the issue as someone else might want to implement.
Will request changes so you can continue on here :)
bugbear.py
Outdated
@@ -366,6 +366,7 @@ class BugBearVisitor(ast.NodeVisitor): | |||
errors = attr.ib(default=attr.Factory(list)) | |||
futures = attr.ib(default=attr.Factory(set)) | |||
contexts = attr.ib(default=attr.Factory(list)) | |||
exceptions_tracked: dict[str, bool | None] = attr.ib(default=attr.Factory(dict)) |
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 highlights we should type annotate all this code. #478
bugbear.py
Outdated
@@ -428,11 +429,16 @@ def visit(self, node): | |||
|
|||
self.check_for_b018(node) | |||
|
|||
def visit_ExceptHandler(self, node): | |||
def visit_ExceptHandler(self, node): # noqa: C901 # too complex |
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.
Wonder if it's worth creating an issue to break this 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.
It is quite messy, with code for B013, B029, B030, B036 and B040 interwoven. Fairly straightforward to split out B013, B029 and B030 though - so I'll just go ahead and do that.
This one is tricky if we want to avoid a false alarm for except:
f = ValueError()
my_exceptions.append(f)
f.add_note("") We don't want to try to detect creation of exceptions, as handling anything other than built-in exceptions would require full-on type tracking. So what we can do is detect when And there's other thorny cases that will raise false alarms even if we limit it to "the my_exc = ValueError()
try:
do_thing()
except ValueError as e:
my_exc.add_note(str(e))
raise my_exc The reason the straightforward case is not vulnerable to this kind of stuff is that the caught exception gets deleted at the end of the exception handler, so we know for sure it's limited to the scope of the |
Hmm, yeah. Some interesting false positives here. I'm happy with not covering this and starting simpler. You do what you want here. I think it's better to start with less false positives and do dedicated PRs handling more complex edge cases in general. You have merge conflicts now to work out now too. |
simplified and cleaned up the code, should be ready for final review. |
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.
Many thanks and very nice. Love the tests with nice comments to see what you're aiming for over the file.
Fixes #474
There's some alternatives when it comes to the scope of this check, namely whether these two should be caught
1
I.e. arbitrary exception created anywhere, that appears to only be used for having a note added. This one gets tricky as its complexity approaches that of a type checker, which usually handles unused variables. If we assume that only exceptions will ever have a method called
add_note
we can sidestep trying to do any type inference.Though this would hit false alarms with stuff like
so it probably isn't worth it.
2
This is essentially the same as the first one, except it's happening within an
except
scope and much more clearly looks like a bug.Handling either case will require
exceptions_tracked
to be a full dict, and the logic in a bunch of places to be beefed up a bit. If we don't care to go with that, I will simplify the type (and rename it, it's an awful name atm) ofexceptions_tracked
and simplify/clean up some code handling it.Handling the lambda case, or other functions defined inside an except handler, wouldn't be super complicated - but I don't really think it's worth even the slight complexity.