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

[Python] [LGTM.com] False-positive: Unreachable statement: #2206 sequel #2351

Open
webknjaz opened this issue Nov 15, 2019 · 3 comments
Open

Comments

@webknjaz
Copy link

webknjaz commented Nov 15, 2019

Description of the false positive

Same as #2206. Except the reproducer contains several subsequent suppress()es:

import contextlib


def some_func():
    with contextlib.suppress(KeyError):
        return dict()['a_key']

    with contextlib.suppress(KeyError):  # LGTM complains that it's unreachable
        return dict()['b_key']

    with contextlib.suppress(KeyError):
        return dict()['c_key']

    return 'fallback'

So I guess #2078 needs more test cases maybe...

URL to the alert on the project page on LGTM.com

https://lgtm.com/projects/g/cherrypy/cheroot/snapshot/0c678bab518ca17151540b7d744faca49b941763/files/cheroot/ssl/builtin.py#x46e331ef60ba4bf1:1

@tausbn
Copy link
Contributor

tausbn commented Nov 16, 2019

This was an interesting case. The problem here is that we are not identifying the calls to suppress as uses of contextlib.suppress. If we follow the definition of suppress, we see that it comes from a compatibility library that -- in the absence of contextlib.suppress (e.g. if the version of Python is too old) -- defines it itself as a fallback.

As it turns out, we are analysing this project as a Python 2.7 project, so this explains why the fallback version of suppress is used.

In this case, I think there's a more general solution that can be applied, without resorting to looking for specific well-known context handlers (which can fail, as the present example shows). Hopefully we should be able to roll out a fix soon.

Thanks for the report!

@tausbn tausbn added the Python label Nov 16, 2019
@webknjaz
Copy link
Author

In this case, I think there's a more general solution that can be applied, without resorting to looking for specific well-known context handlers (which can fail, as the present example shows).

Right, any context manager can choose to suppress exceptions via its __exit__() method.

@webknjaz
Copy link
Author

Got another instance of this: https://lgtm.com/projects/g/ansible/ansible-lint/snapshot/4741210b9feefe9ed54c59a731c1636fd648400e/files/lib/ansiblelint/utils.py?sort=name&dir=ASC&mode=heatmap#x92b14f87ccfa33b7:1

Basically, the same except it uses continue in place of return:

for ...:
    contextlib.suppress(Exc):
        ...
        continue

    some_code  #  <-- marked as unreachable but in fact, is totally reachable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants