X Tutup
The Wayback Machine - https://web.archive.org/web/20220516120050/https://github.com/python/cpython/issues/92739
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

Warning for foo == "bar" or "baz" #92739

Open
Akuli opened this issue May 12, 2022 · 9 comments
Open

Warning for foo == "bar" or "baz" #92739

Akuli opened this issue May 12, 2022 · 9 comments
Labels
interpreter-core type-feature

Comments

@Akuli
Copy link
Contributor

@Akuli Akuli commented May 12, 2022

Feature or enhancement

Emit SyntaxWarning for code like if foo == "bar" or "baz". It should be written as if foo == "bar" or foo == "baz", or perhaps if foo in ("bar", "baz"). The warning is emitted only if "bar" and "baz" here are string literals or number literals as in if foo == 1 or 2.5, but foo can be any expression. Maybe also do the same for while and assert.

Pitch

Currently there's no warning, the if statement just silently does the wrong thing. I have helped many people to learn programming in Python, and in my experience, this is a mistake that every beginner makes at some point during their learning.

In an if statement, a condition like ... or "some hard-coded string" always evaluates to a truthy value (unless the string is empty in which case the or "" can be safely removed). So in this context, or "some_string" can't really be intentional. It's an error and it shouldn't pass silently, but it does.

Alternative ideas that I thought of and rejected:

  • Adding this to a linter instead of CPython: Beginners don't know what a linter is, and many beginners don't use an IDE that runs linters in the background. Whether or not they should is a matter of opinions :)
  • The or operator raising runtime error if one of the operands is a string. Breaks correct code like return foobar or "some default value". Would also be ridiculously slow.

CPython already emits a similar warning for assert(condition, message), which asserts that a tuple of two elements is truthy.

@Akuli Akuli added the type-feature label May 12, 2022
@nedbat
Copy link
Member

@nedbat nedbat commented May 12, 2022

I think this would be great.

@zware zware added the interpreter-core label May 12, 2022
@sweeneyde
Copy link
Member

@sweeneyde sweeneyde commented May 12, 2022

I opened #92747

@oda-gitso
Copy link

@oda-gitso oda-gitso commented May 13, 2022

I could see this being useful.

However, this need not be a problem if users are familiar with operator precedence rules or know where to look it up.

@serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented May 13, 2022

I do not think this should be added in the compiler. It will complicate the code for very tiny benefit. Such kind of mistakes are only made by beginners which learn programming. It is easy to catch when it happen the first time, and it is unimaginative that anybody make it the second time.

In contrary, the mistake in assert(condition, message) can be made even by experience programmer if he came from other programming language, and it is difficult to catch it, because it just "works", until it should fail, but do not fail, and in otherwise correct program it never fails.

@Akuli
Copy link
Contributor Author

@Akuli Akuli commented May 13, 2022

It is easy to catch when it happen the first time

I have quite the opposite experience. I know a friend who was working on a non-trivial size program (hundreds of lines) when this happened to him for the first time. If I hadn't pointed it out in a review, the program would have behaved badly in a corner case that happens somewhat rarely. He didn't notice it himself when testing.

@sweeneyde
Copy link
Member

@sweeneyde sweeneyde commented May 14, 2022

Hm, I'm sort of on the fence about this. On one hand, it is an extremely common issue on StackOverflow. This question has 1,294 questions linked to/from it including many, many duplicates.

I do buy the argument that the best tool to detect this is a linter, and needless complexity should be avoided, but I also think this might give a bit of benefit to beginners. I would defer to those with more experience teaching beginners though. I would assume that issue would be particular to those learning Python as their first programming language.

@ronaldoussoren
Copy link
Contributor

@ronaldoussoren ronaldoussoren commented May 14, 2022

Hm, I'm sort of on the fence about this. On one hand, it is an extremely common issue on StackOverflow. This question has 1,294 questions linked to/from it including many, many duplicates.

I do buy the argument that the best tool to detect this is a linter, and needless complexity should be avoided, but I also think this might give a bit of benefit to beginners. I would defer to those with more experience teaching beginners though. I would assume that issue would be particular to those learning Python as their first programming language.

IMHO The proposed warning can only find a very limited subset of possibly problematic patterns without resulting in a high level of false positives.

The stack overflow question you link to is an example of that. That refers to "a or b or c == 2". In the context of that question it is clear that the OP should have used "a == 2 or b == 2 ...", but I've used similar code patterns where the code as written was correct.

@sweeneyde
Copy link
Member

@sweeneyde sweeneyde commented May 14, 2022

@Akuli
Copy link
Contributor Author

@Akuli Akuli commented May 15, 2022

There seems to be 3 different opinions about this:

  1. Should be added to cpython
  2. Complicates code too much and belongs to a linter (@rhettinger)
  3. Complicates code too much and isn't useful

For opinion 3:

IMHO The proposed warning can only find a very limited subset of possibly problematic patterns without resulting in a high level of false positives.

I don't see how limited implies it's useless. Beginners use more hard-coded strings and ints in their if checks than experienced users, so restricting this to hard-coded values doesn't matter very much. The list above shows this quite clearly.

This one boils down to whether we want "simple is better than complex" or "practicality beats purity". To me, a warning like this seems very practical, while others prefer keeping the compiler simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core type-feature
Projects
None yet
Development

No branches or pull requests

7 participants
X Tutup