Skip to content
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 except* support to B012&B025 #500

Merged
merged 2 commits into from
Dec 11, 2024
Merged

Conversation

jakkdl
Copy link
Contributor

@jakkdl jakkdl commented Dec 5, 2024

This PR creates a visit_TryStar that mostly just calls visit_Try, enabling B012 & B025 to work with try/except*

Because ExceptHandler is also used for TryStar, we already have support for free for B014, B029, B030, B036 and B904.
I opted to add tests for them anyway, but it did end up with a somewhat silly amount of added tests - most of which are just pure copy-paste's of their original test files. Another option is writing a single except_star.py file that tests all of them, or writing a transformer test that goes through the original files, does a search+replace for except->except*, and then tests them on the fly. Though the latter option would also involve some rejigging to get the expected errors shared from the original test_bxxx functions.
Another case for #419

B001 is the only except-related rule I found that's not revelant, since except*: is a syntax error.

EDIT: error message updates added in adca610
I have not updated error messages. For B012 (unclear if necessary) and B025 it'd be fairly straightforward, could make visit_TryStar pass a parameter to check_for_b012/check_for_b025. For the others it'd have to involve a property BugBearVisitor.in_trystar... I guess I should just do that, even if somewhat tedious.

@cooperlees
Copy link
Collaborator

I think the simple copy paste for tests is usually worth it over more complext helper functions etc. - But I see here how our tests simplicity create annoying amounts of fun ...

I don't think I want a except_star.py ... As for updated messages, it's just the same error inside a try/except right? If so, I don't think we need to change the messages. If I've missed context just share. But PR seems good to me.

@jakkdl
Copy link
Contributor Author

jakkdl commented Dec 9, 2024

I think the simple copy paste for tests is usually worth it over more complext helper functions etc. - But I see here how our tests simplicity create annoying amounts of fun ...
I don't think I want a except_star.py ...

I might give #419 a shot, in which case keeping to the current structure also makes it simpler. The downside of copy-paste would be having to maintain multiple copies, but that shouldn't be much of an issue here since these test files shouldn't see much/any changes in the future (and extremely unlikely that behavior would differ between except/except*).

As for updated messages, it's just the same error inside a try/except right? If so, I don't think we need to change the messages. If I've missed context just share. But PR seems good to me.

Yeah it's literally just saying Using except* (): with an empty tuple does not handle/catch anything... instead of Using except (): with an empty tuple does not handle/catch anything.... I can revert the last commit if you think the complexity cost to the code is higher than the gain from printing the *. Given that you can't have multiple except/except* on the same line it's unlikely to lead to confusion.

@jakkdl jakkdl marked this pull request as ready for review December 9, 2024 12:03
Copy link
Collaborator

@cooperlees cooperlees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All sounds good to me. I'll leave the complexity choice to you.

One thing I don't see how it works, are our checks for except* now somehow recursive to now include all subclasses for the specified exception(s)? If so how, is it inbuilt to the methods used somehow?

@jakkdl
Copy link
Contributor Author

jakkdl commented Dec 9, 2024

All sounds good to me. I'll leave the complexity choice to you.

I'll just keep it as is then. Matches ruff as well.

One thing I don't see how it works, are our checks for except* now somehow recursive to now include all subclasses for the specified exception(s)? If so how, is it inbuilt to the methods used somehow?

I don't follow, what is this referring to?

@cooperlees
Copy link
Collaborator

I don't follow, what is this referring to?

What makes our checks know about except*'s ability to resolve the subclasses for exception(s) the code specifies? So we don't get noise when we flag an error, but a subclass would make it valid ... (don't know how to explain it another way to be honest).

@jakkdl
Copy link
Contributor Author

jakkdl commented Dec 10, 2024

I don't follow, what is this referring to?

What makes our checks know about except*'s ability to resolve the subclasses for exception(s) the code specifies? So we don't get noise when we flag an error, but a subclass would make it valid ... (don't know how to explain it another way to be honest).

except and except* doesn't differ in any meaningful way here, no? And looking through the list of rules I'm not seeing any that cares about resolving subclasses?
If you can come up with a code example that you're surprised doesn't raise an error I'm all ears :)

@cooperlees
Copy link
Collaborator

I think I'm mis-understanding the use of except* ... I've never used it. I'll trust you here it's all good.

@cooperlees cooperlees merged commit b960272 into PyCQA:main Dec 11, 2024
7 checks passed
@jakkdl jakkdl deleted the except_star_support branch December 12, 2024 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants