-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Detect impossible condition caused by user defined __bool__ #7008
Comments
Well mypy doesn't detect even simpler unreachable function calls like Related to #2395 |
#6990 is another example where this may be useful. |
FWIW I've started sort of looking into adding in some kind of flag for this during the past week (I'm already poking around this corner of the codebase for literal and enum reachability stuff anyways). I think in principle it should be straightforward: to avoid false-positives with things like We'll also probably want to adjust mypy so it distinguishes between intentionally and unintentionally unreachable blocks. E.g. if somebody does TBH I think the hardest/most annoying part will be constructing an understandable error message for subexpressions that were skipped due to being unreachable, just due to the "line-by-line" nature of error reporting in mypy. Possibly adding in a "fyi this expression is always True/always False" error message might be sufficient instead, as opposed to indicating specific ignored subexpressions. Not sure, still need to do more poking around. |
On Python 3.8 there is a simple solution for that:
On the other hand adding a |
There are better ways to stop code executing than `if False`
…On Wed, 19 Jun 2019, 18:47 Ivan Levkivskyi, ***@***.***> wrote:
TBH I think the hardest/most annoying part will be constructing an
understandable error message for subexpressions that were skipped due to
being unreachable, just due to the "line-by-line" nature of error reporting
in mypy.
On Python 3.8 there is a simple solution for that:
ast.get_source_segment() gives exact source code for every AST node. But
maybe a more generic error message would be sufficient.
E.g. if somebody does if False: ... that was probably intentional
On the other hand adding a # type: ignore to that code of switching it to if
typing.TYPE_CHECKING: ... is probably a fine solution too.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#7008?email_source=notifications&email_token=AADFATGXR2YJJHFE7MUITDDP3JWMLA5CNFSM4HYYMF42YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYCUNNA#issuecomment-503662260>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADFATANVYUWKTOBP7OLMNTP3JWMLANCNFSM4HYYMF4Q>
.
|
This diff adds a `--disallow-inferred-unreachable` flag that reports an error if: 1. Any branch is inferred to be unreachable 2. Any subexpression in boolean expressions, inline if statements, and list/set/generator/dict comprehensions are always unreachable or redundant. This only takes into account the results of *type* analysis. We do not report errors for branches that are inferred to be unreachable in the semantic analysis phase (e.g. due to `sys.platform` checks and the like). Those checks are all intentional/deliberately flag certain branches as unreachable, so error messages would be annoying in those cases. A few additional notes: 1. I didn't spend a huge amount of time trying to come up with error messages. They could probably do with some polishing/rewording. 2. I thought about enabling this flag for default with mypy, but unfortunately that ended up producing ~40 to 50 (apparently legitimate) error messages. About a fourth of them were due to runtime checks checking to see if some type is None (despite not being declared to be Optional), about a fourth seemed to be due to mypy not quite understanding how to handle things like traits and Bogus[...], and about a fourth seemed to be legitimately unnecessary checks we could safely remove. The final checks were a mixture of typeshed bugs and misc errors with the reachability checks. (e.g. see python#7048) 3. For these reasons, I decided against adding this flag to `--strict` and against documenting it yet. We'll probably need to flush out a few bugs in mypy first/get mypy to the state where we can at least honestly dogfood this. Resolves python#2395; partially addresses python#7008.
This diff adds a `--warn-unreachable` flag that reports an error if: 1. Any branch is inferred to be unreachable 2. Any subexpression in boolean expressions, inline if statements, and list/set/generator/dict comprehensions are always unreachable or redundant. This only takes into account the results of *type* analysis. We do not report errors for branches that are inferred to be unreachable in the semantic analysis phase (e.g. due to `sys.platform` checks and the like). Those checks are all intentional/deliberately flag certain branches as unreachable, so error messages would be annoying in those cases. A few additional notes: 1. I thought about enabling this flag for default with mypy, but unfortunately that ended up producing ~40 to 50 (apparently legitimate) error messages. About a fourth of them were due to runtime checks checking to see if some type is None (despite not being declared to be Optional), about a fourth seemed to be due to mypy not quite understanding how to handle things like traits and Bogus[...], and about a fourth seemed to be legitimately unnecessary checks we could safely remove. The final checks were a mixture of typeshed bugs and misc errors with the reachability checks. (e.g. see #7048) 2. For these reasons, I decided against adding this flag to `--strict` and against documenting it yet. We'll probably need to flush out a few bugs in mypy first/get mypy to the state where we can at least honestly dogfood this. Resolves #2395; partially addresses #7008.
It looks like #7454 will help with this. @Michael0x2a is there something else apart from better error location needed for this issue? If not, I would propose to close this one. |
Actually I think |
FWIW mypy is now capable of warning on ilevkivskyi's case with from typing import *
def some_foo() -> Literal[True]:
return True
def throw_error():
raise Exception
if __name__ == '__main__':
print(some_foo() or throw_error())
# ^^^^^^^^^^^^^ error: Right operand of "or" is never evaluated [unreachable] It doesn't handle Should we close this or keep it open for extra |
Yeah, let's keep this open for |
Eg with the following:
mypy should be able to detect that the call to throw_error is unreachable
The text was updated successfully, but these errors were encountered: