2

The question I'm about to ask here has been asked before, but those questions/answers make no mention of what I want to know.

I recall a few months or so ago, I had a rather sizable Python script, and I was using if x: because it was shorter and I was lazy. I don't remember which version of Python, but I do remember getting a DeprecationWarning (or PendingDeprecationWarning?) about implicit comparisons to True.

Now, I'm trying to write something someone else might read. I'm using if x == True and if x is not None everywhere, and pep8 and pylint are complaining about this, saying I should use if x:.

Personally, I think if x: is far less readable, but pep8 (the program) and PEP 8 (the document) both disagree.

Google is not being very helpful in allowing me to figure in which version, if ever, Python gave a DeprecationWarning for if x:, so I wonder if perhaps the SO community can provide insight.

Should I be worrying about this at all? Does it actually matter that much?

Community
  • 1
  • 1
cat
  • 3,888
  • 5
  • 32
  • 61
  • 1
    Did you try `if 1:`? The if condition still holds. I prefer `if x==True`.[*Explicit is better than implicit*](https://www.python.org/dev/peps/pep-0020/) – Bhargav Rao Jan 12 '16 at 14:30
  • 3
    In the script that was giving the warning, what was the type of `x`? It may be the library that defines that type has deprecated conversion to `bool`. – jwodder Jan 12 '16 at 14:30
  • 1
    @BhargavRao I know how `==` and `is` and comparisons to `True` and `None` *work*, that's not what I'm asking about. – cat Jan 12 '16 at 14:32
  • 1
    Well, this is pretty much arguing about taste. `PEP-8` is a style suggestion, and a good one at that. But it is in no way a requirement, so you are definitely allowed to deviate if you feel it improves readability. Just be consistent about it! From `import this`: _Readability counts._ – Nelewout Jan 12 '16 at 14:32
  • @jwodder The script doesn't use any non-builtin types, just strings, ints and bools. – cat Jan 12 '16 at 14:33
  • 1
    @N.Wouda well, when I'm confident with the completeness of this script I intend to post it to [CodeReview.SE] (and not get a going-over for not being PEP 8 compliant), and I *like* `pep8` and its guidelines. – cat Jan 12 '16 at 14:35
  • 7
    `if x:` is perfectly standard Python, and the preferred form when `x` is boolean. It *has* to be some kind of class that was generating the error. – Mark Ransom Jan 12 '16 at 14:37
  • 1
    @cat: it is perfectly good Python, and Python 3.+ versions don't give a warning, so if you're writing code for other people to work with in the future, using `if x:` is perfectly fine. And by the way, on behalf of every developer who had to maintain horribly unreadable code, THANK YOU for considering the readability of your code. :) – gariepy Jan 12 '16 at 14:41
  • @gariepy post that as an answer and I'll accept it! – cat Jan 12 '16 at 14:47

3 Answers3

2

The correct answer as to what condition to use is, in the first place, a matter of semantics rather than style. Unless x is a boolean value, 0/False or 1/True, which your question did not specify, if x: and if x == True: are semantically different conditions and often give different results. You should use whichever is the correct one for the situation. if x: is usually the correct choice, but not always. If x is specified (known) to be a boolean, then adding == True is superfluous and a waste of time for the writer, reader, and interpreter.

Under the covers, if x: means (is implemented as) if bool(x) is True in the normal meaning of this expression, and if x == True: means if bool(x == True) is True. Since x == True return a bool and bool(a_bool) is a_bool, the latter reduces to if (x == True) is True. In general, bool(x) is not the same as x == True.

if x is None: (or not None) should be used if and only if that is the proper condition. It often correct when testing the output of a function returns either an int (or string or ...) or None. In many other situations, it is usually wrong.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
1

It is perfectly good Python, and Python 3.+ versions don't give a warning, so if you're writing code for other people to work with in the future, using if x: is perfectly fine. And by the way, on behalf of every developer who had to maintain horribly unreadable code, THANK YOU for considering the readability of your code.

gariepy
  • 3,576
  • 6
  • 21
  • 34
0

I think you have several separate issues confused.

It's best to check what the style guide actually says, and double check how your code actually behaves, rather than relying only on remembered behaviour :-)

Boolean expressions are already either true or false

The expression in an if statement is always intepreted as boolean; anyone reading Python code needs to know that anyway.

So the following all mean exactly the same thing, and piling on == True does not improve readability:

if x + y:
    …

if (x + y) == True:
    …

if ((x + y) == True) == True:
    …

if (((x + y) == True) == True) == True:
    …

which is why PEP 8 says:

Don't compare boolean values to True or False using == .

Singletons should be compared using identity

The comparison of an object to None implies that value is treated specially; it is commonly used as a sentinel for special processing. It is a singleton, so comparing whether an object is merely equal to None is ambiguous.

So, if your intent is to test a value for None, you should test whether the object is none by testing its identity:

if x is None:
    …

if x is not None:
    …

which is why PEP 8 says:

Comparisons to singletons like None should always be done with is or is not , never the equality operators.

None is not the only value that is boolean false

There are many values which are false in a boolean context, so doing a mere if x: is not enough to tell whether an object is actually None.

Which is why PEP 8 says:

beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value.

bignose
  • 30,281
  • 14
  • 77
  • 110