I've found a surprising sentence in the Python documentation under Truth Value Testing:
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated.
Relational operators seem to have no excepting statements, so IIUC they could return 0 and 1 instead of False and True on values of some built-in types (e.g. 7 < 3), even nondeterministically.
Thus, in order to satisfy a specification requiring of my code to produce values of type bool or for defensive programming (whenever that's important), should I wrap logical expressions in calls to bool?
Additional question: why does this latitude exist? Does it make things easier somehow for CPython or another implementation?
EDIT The question has been answered and I've accepted, but I'd like to add that in PEP 285 – Adding a bool type I've found the following statements:
- All built-in operations that conceptually return a Boolean result will be changed to return False or True instead of 0 or 1; for example, comparisons, the “not” operator, and predicates like isinstance().
- All built-in operations that are defined to return a Boolean result will be changed to return False or True instead of 0 or 1. In particular, this affects comparisons (<, <=, ==, !=, >, >=, is, is not, in, not in), the unary operator ‘not’, the built-in functions callable(), hasattr(), isinstance() and issubclass(), the dict method has_key(), the string and unicode methods endswith(), isalnum(), isalpha(), isdigit(), islower(), isspace(), istitle(), isupper(), and startswith(), the unicode methods isdecimal() and isnumeric(), and the ‘closed’ attribute of file objects. The predicates in the operator module are also changed to return a bool, including operator.truth().
- The only thing that changes is the preferred values to represent truth values when returned or assigned explicitly. Previously, these preferred truth values were 0 and 1; the PEP changes the preferred values to False and True, and changes built-in operations to return these preferred values.
However, PEPs seem to be less authoritative than the documentation (of which the language and library references are the main parts) and there are numerous deviations from PEPs (many of them mentioned explicitly). So until the team updates it, the stronger guarantees of the PEP aren't to be trusted, I think.
EDIT I've reported it on GH as a Python issue
So, it is probably important to understand that
boolobjects areintobjects, sinceissubclass(bool, int)is true.So
isinstance(True, int) and isinstance(False, int)is true.Prior to version 2.3 which was released back in 2002, Python lacked a
booltype. PEP 285 was the accepted proposal. Prior to this, these operations would return0or1. You can read in "WhatsNew" for 2.3:So, I can only surmise that the language was kept to include
0and1while the standard library etc caught up with this change. But by now, I think everything in built-ins and every part of the standard library I've used will returnboolwhen the return value is meant to be a boolean.But keep in mind, from the release notes: