Skip to content

False negative for no-else-return after except #7788

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

Closed
nickdrozd opened this issue Nov 17, 2022 · 3 comments · Fixed by #7888
Closed

False negative for no-else-return after except #7788

nickdrozd opened this issue Nov 17, 2022 · 3 comments · Fixed by #7888
Assignees
Labels
False Negative 🦋 No message is emitted but something is wrong with the code Good first issue Friendly and approachable by new contributors
Milestone

Comments

@nickdrozd
Copy link
Contributor

nickdrozd commented Nov 17, 2022

Bug description

This snippet returns in the except block, and therefore the else is unnecessary:

def f() -> bool:
    try:
        print('asdf')
    except:  # pylint: disable = bare-except
        return False
    else:
        return True

It should raise no-else-return.

Configuration

No response

Command used

`pylint asdf.py`

Pylint output

No warnings raised

Expected behavior

Should raise no-else-return

Pylint version

pylint 2.16.0-dev
astroid 2.13.0-dev0
Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
@nickdrozd nickdrozd added Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling False Negative 🦋 No message is emitted but something is wrong with the code Good first issue Friendly and approachable by new contributors and removed Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Nov 17, 2022
@nickdrozd
Copy link
Contributor Author

A similar case with raise:

    def _load_reporter_by_name(self, reporter_name: str) -> reporters.BaseReporter:
        name = reporter_name.lower()
        if name in self._reporters:
            return self._reporters[name]()

        try:
            reporter_class = _load_reporter_by_class(reporter_name)
        except (ImportError, AttributeError, AssertionError) as e:
            raise exceptions.InvalidReporterError(name) from e
        else:
            return reporter_class()

The except raises an exception, so the else is not needed.

@marcinnformula
Copy link

marcinnformula commented Sep 5, 2023

What?!

I don't understand why no-else-return affects try-except-else.

I also don't understand why else is "unnecessary" here:

def test_exception(raise_exception=True):
    try:
        if raise_exception:
            raise ValueError
    except ValueError:
        return "exception raised"
    else:
        return "exception NOT raised"

Yes, this is an equivalent of:

def test_exception(raise_exception=True):
    try:
        if raise_exception:
            raise ValueError
    except ValueError:
        return "exception raised"
    return "exception NOT raised"

But please note that explicit else block is for:

  1. readability (PEP20)
  2. avoiding negative cons due to possible refactoring in except block when removing return (that would change the flow)

#7888 should be reverted

@Pierre-Sassoulas
Copy link
Member

Could you open a new issue @marcinnformula, a comment on a closed issue is going to be forgotten. I don't think we should revert but we could introduce an option or a way to distinguish the two use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
False Negative 🦋 No message is emitted but something is wrong with the code Good first issue Friendly and approachable by new contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants