Skip to content

Unreachable with always true/false operands to and/or #8711

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
llchan opened this issue Apr 23, 2020 · 3 comments · Fixed by #9125
Closed

Unreachable with always true/false operands to and/or #8711

llchan opened this issue Apr 23, 2020 · 3 comments · Fixed by #9125

Comments

@llchan
Copy link
Contributor

llchan commented Apr 23, 2020

It appears that an always true/false operand into and/or is marked as unreachable, even when it doesnt cause the other operand to be short circuited away (that scenario is correct, and emits a different "is never evaluated" message). The examples below are obviously very contrived; a more real-world example is something like

assert isinstance(x, float) and x > 0.0

  • Are you reporting a bug, or opening a feature request? bug
  • Please insert below the code you are checking with mypy.
    True and True
  • What is the actual behavior/output?
    main.py: note: In function "foo":
    main.py:1:1: error: Left operand of 'and' is always true  [unreachable]
            True and True
            ^
    
  • What is the behavior/output you expect? Success
  • What are the versions of mypy and Python you are using? master (0.770+dev.833fc2caec6773683d691a72058293ae87139210) with CPython 3.7.7
  • What are the mypy flags you are using? Custom, but effectively --strict
@Michael0x2a
Copy link
Collaborator

Mypy is warning about this since an always-true subcondition of an 'and' statement usually indicates that there's some bug or redundancy in the code.

In your first real-world example, the bug/redundancy is that your code contains what appears to be (from mypy's point of view) an unnecessary runtime check. This might be a sign that some dynamically-typed part of your code isn't being contained fully cleanly from the statically-typed part, that some earlier type hint needs to be broadened, that you ran into a mypy bug causing it to infer a too-narrow type...

That said, you get this warning only when using the `--warn-unreachable flag, which I do think is a bit confusing since everything is actually reachable here. This warning was bundled with that flag mostly because it was convenient from an implementation perspective, but maybe it might be better to split it out into a separate flag? Not sure -- mypy arguably has too many flags.

At the very least, we could use a different error code here -- e.g. "[redundant]" instead of "[unreachable]". (If you want to try taking a swing at fixing this part, here's where to find the unreachable/redundant error messages.)

@llchan
Copy link
Contributor Author

llchan commented Apr 23, 2020

Got it. Yeah I can see the benefit of having warnings about expressions that are statically true/false. Splitting the the error code would go a long way in making this more clear and independently configurable, so I can look into that.

Medium-term, something that would make the "[redundant]" check more useful would be to auto-ignore inside an assert expression, since it's not uncommon to express invariants in asserts.

@llchan
Copy link
Contributor Author

llchan commented Apr 23, 2020

Also just to be clear about motivation, you are right that redundant isinstance checks are perhaps a sign of something mis-typed upstream. However, when writing a library for users that may not use mypy, it's prudent to be a bit more defensive at runtime, even if the types are specified in the annotations and in theory something should be always-true.

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 a pull request may close this issue.

2 participants