Skip to content

Add rule raise-missing-from #3695

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

Merged

Conversation

cool-RR
Copy link
Contributor

@cool-RR cool-RR commented Jun 16, 2020

Steps

  • Add yourself to CONTRIBUTORS if you are a new contributor.
  • Add a ChangeLog entry describing what your PR does.
  • If it's a new feature or an important bug fix, add a What's New entry in doc/whatsnew/<current release.rst>.
  • Write a good description on what the PR does.

Description

Implement #3687

Type of Changes

Type
🐛 Bug fix
✨ New feature
🔨 Refactoring
📜 Docs

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch 21 times, most recently from 95c5adf to a59fd6e Compare June 16, 2020 15:16
@coveralls
Copy link

coveralls commented Jun 16, 2020

Coverage Status

Coverage increased (+0.0004%) to 90.707% when pulling fb7d5cf on cool-RR:2020-06-16-raise-missing-from into 35f838f on PyCQA:master.

@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 16, 2020

@Pierre-Sassoulas @PCManticore

Here's my attempt to implement this feature. This is my first PyLint rule, so I'm likely to miss important things. Also I didn't write the documentation yet, because I need to know whether I'm even on the right track with this implementation. Let me know.

@Pierre-Sassoulas Pierre-Sassoulas linked an issue Jun 16, 2020 that may be closed by this pull request
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

The codes looks fine to me, good work ! I just think there should be two or three more functional tests (using "from" explicitly to reraise). I made some suggestions.

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch 2 times, most recently from 45151fa to 7998fa0 Compare June 16, 2020 17:11
@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 16, 2020

@Pierre-Sassoulas See the iterate_parents function I'm implementing. I have the feeling there's a better way to search for an enclosing except. Do you know of one?

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from 7998fa0 to 5b561ac Compare June 16, 2020 17:14
cool-RR added a commit to cool-RR/pylint that referenced this pull request Jun 16, 2020
@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch 5 times, most recently from 1ea39ff to d363377 Compare June 16, 2020 18:16
@cool-RR cool-RR marked this pull request as ready for review June 16, 2020 19:07
@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from d363377 to 4cb43b8 Compare June 16, 2020 19:08
@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 16, 2020

@Pierre-Sassoulas Any idea why Travis doesn't seem to be running?

@Pierre-Sassoulas
Copy link
Member

It can be long to launch some times. If it's still not running running you can force push with a new date for the commit to trigger the pipeline.

@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 16, 2020

I did the force push, it didn't help.

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from 4cb43b8 to f5e1485 Compare June 16, 2020 19:48
@Pierre-Sassoulas
Copy link
Member

@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 16, 2020

@Pierre-Sassoulas That doesn't make sense. I'm getting this error in the build:

/home/travis/build/PyCQA/pylint/pylint/checkers/exceptions.py:86:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)

Even though I already fixed it in my code. Could it be running on an old version?

@Pierre-Sassoulas
Copy link
Member

If nothing in iterate_ancestors(node) is an astroid.ExceptHandler or an astroid.scoped_nodes.LocalsDictNodeNG the function return is an implicit None. You should add return None line 96 in pylint/checkers/exceptions.py.

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from f5e1485 to b88e989 Compare June 16, 2020 20:13
@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 17, 2020

@Pierre-Sassoulas

Cool, fixed.

I thought of something. This check should only be applied in Python 3 codebases. Should I mark it in some way as a Python 3-only check?

Copy link
Contributor

@PCManticore PCManticore left a comment

Choose a reason for hiding this comment

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

Super nice PR @cool-RR ! Thanks a lot. No worries regarding marking this as a Python 3 checker, as pylint already runs only on Python 3.

@@ -76,6 +76,26 @@ def _is_raising(body: typing.List) -> bool:
return False


def iterate_ancestors(node: NodeNG) -> typing.Iterator[NodeNG]:
Copy link
Contributor

Choose a reason for hiding this comment

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

These two functions can be replaced with pylint.checkers.utils.find_try_except_wrapper_node:

except_handler = find_try_except_wrapper_node(node)
if isinstance(except_handler, astroid.ExceptHandler):
    # it's found

On a quick look that function will need some adjustments to make it work for this use case, but it's better than having another except handler searching routine in the code base.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It'll need 2 adjustments. One is adding an argument stop_on_function: bool = False and logic for it, that's pretty straightforward. Also consider that it's possible that the fact we haven't had this logic until now causes bugs in other checks, as code that's in a function defined in try-except doesn't have the same behavior as code that's actually in try-except. I won't dwell on that, you can open an issue on that if you'd like.

The second would be for it to find just the except clause, and not the try clause. Now, I don't know what kind of API you want for that. I can add an argument only_except: bool = False but that's not a nice API. Let me know which API you'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@PCManticore

I fixed the merge conflict. Besides this issue that I'm waiting on a response on from you, is there anything else that needs to be done before this PR can be merged?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nudge.

Copy link
Contributor

Choose a reason for hiding this comment

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

To answer your question:

  • The function should only look in the current scope so it should stop if it encounters a FunctionDef or a ClassDef.
  • We can split this function into two, one for finding TryExcept nodes, another for finding the parent ExceptHandler, or we can rely on isinstance after the function call returned to deduce the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can split this function into two, one for finding TryExcept nodes, another for finding the parent ExceptHandler.

Okay, I pushed that now.

@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from b88e989 to 4e08206 Compare June 17, 2020 07:30
@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch 3 times, most recently from 1b04ea7 to 6b5bfa0 Compare June 20, 2020 10:41
@cool-RR cool-RR force-pushed the 2020-06-16-raise-missing-from branch from 6b5bfa0 to fb7d5cf Compare June 20, 2020 10:50
@PCManticore PCManticore merged commit a735857 into pylint-dev:master Jun 22, 2020
@cool-RR
Copy link
Contributor Author

cool-RR commented Jun 22, 2020

Woohoo!

denewiler pushed a commit to triboelectric/statick that referenced this pull request Aug 27, 2020
* Format all Python files with latest version of black (20.8b1).
* Add `from` keyword when re-raising exceptions.
  * pylint W0707: raise-missing-from
  * https://pylint.readthedocs.io/en/latest/technical_reference/features.html
  * pylint-dev/pylint#3695
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.

Feature request: Add a check for raise foo from bar
4 participants