-
Notifications
You must be signed in to change notification settings - Fork 59
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
How should try-except clauses be modeled? #28
Comments
If implemented, this change would cause the complexity of try statements to be a multiplication of the complexity of the main block by the number of handlers. This might actually be correct, but would be quite different from the current behavior. It would certainly motivate the best-pratice of only ever putting a single statement in the main try clause. Also see discussion at #26 |
That graph I drew was wrong. I meant for the except clauses to converge on the
Also, I'm okay with prodding people into only writing the import sys
def f():
try:
raise ValueError('Some message')
except ValueError:
sys.exit(1)
finally:
print("Yes finally blocks get executed even if the except clause runs sys.exit")
print("But this will not get executed unless there's no exception raised.") So really you have the above graph (although simplified) and now you have an edge pointing from finally to the print and you could realistically have an edge leading wherever the body of the specific |
You should graph out your last idea. If you're talking about leaving some nodes dangling, I noticed that our calculation doesn't seem to work for trees with more than one leaf:
E - N + 2 ==> 5 - 6 + 2 = 1 Wikipedia seems to indicate that we need to connect all exit points back to the entry point and add 1 instead of 2:
8 - 6 + 1 = 3 I suppose this is equivalent to the current practice of making sure all "loose ends" are connected back to a single "bottom" point.
8 - 7 + 2 = 3 |
IMHO it's a mistake to think that the problem here is exception handlers. The problem is exceptions. In Python, almost any statement may result in an exception (which effectively means branching to the end of the function, if there's no exception handler), so in theory the graph should have a branch from every node to the end of the function. (In fact, exceptions from signals, like KeyboardInterrupt, can be raised after any opcode, so you might need to add even more nodes.) Clearly actually doing this would turn mccabe into a glorified line counter, which is not a useful tool. It's reasonable to decide that mccabe, in order to be a useful tool, doesn't take into account the possibility that exceptions may be raised at any point in the code. What is not reasonable IMHO is to decide that it does take that into account, but only inside try blocks. Exceptions may occur anywhere, not just in try blocks. |
@zaneb I think it's clear that we want to fix this. Do you have time to fix this? I'm happy to review and merge a PR that rectifies this (known imperfect) situation. |
@sigmavirus24 did you mean to leave that comment on #27 rather than here? FWIW I have no plans to work on this. |
Yes, I agree with @zaneb above. The end result is that This is a pretty big change though, and some users will find it quite surprising. |
This is an old issue but I want to chime in that I think it's a really good idea - I think this would be a really good way to convince developers that try: except blocks should be short and specific. |
From @sigmavirus24
Actually now that I think of a more complex example
I see that actually you could branch to any of the except clauses from either of the statements in the try block. I still don't think that the except branches coming from the try block is correct so maybe something like
The text was updated successfully, but these errors were encountered: