Truth Value Testing
The truth value testing of RPython is similar with Python.
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
None
False
zero of any numeric type, for example,
0
,0L
,0.0
.any empty sequence, for example,
''
,()
,[]
.any empty mapping, for example,
{}
.
All other values are considered true — so objects of many types are always true.
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. (Important
exception: the Boolean operations or
and and
always return one of their
operands.)
def truth_value_testing():
if None or \
False or \
0 or \
0L or \
0.0 or \
'' or \
() or \
[] or \
{}:
print("Some values are True.")
else:
print("None, False, 0, 0L, 0.0, '', (), [], {} are considered False.")
def entry_point(argv):
truth_value_testing()
return 0
def target(*args):
return entry_point
if __name__ == "__main__":
import sys
entry_point(sys.argv)
Attention
However, there is one inconsistency. In Python, the following values are considered false:
instances of user-defined classes, if the class defines a
__nonzero__()
or__len__()
method, when that method returns the integer zero orbool
valueFalse
.
In RPython, the above values are considered true.
For example, we have two classes: ZeroLen
and NonZero
. They define
__len__()
and __nonzero__()
methods respectively. Truth value testing of
instances of ZeroLen
and NonZero
are different in RPython and Python.
class ZeroLen():
def __len__(self):
return 0
class NonZero():
def __nonzero__(self):
return False
def truth_value_testing_inconsistency():
zero_len = ZeroLen()
non_zero = NonZero()
if zero_len:
print("zero_len is True in RPython.") # RPython
else:
print("zero_len is False in Python.") # Python
if non_zero:
print("non_zero is True in RPython.") # RPtyhon
else:
print("non_zero is False in Python.") # Python
def entry_point(argv):
truth_value_testing_inconsistency()
return 0
def target(*args):
return entry_point
if __name__ == "__main__":
import sys
entry_point(sys.argv)
However, the execution results are inconsistent using RPython and Python
$ rpython truth_value_testing_inconsistency.py # compile with RPython
$ ./truth_value_testing_inconsistency-c
zero_len is True in RPython.
non_zero is True in RPython.
$ python truth_value_testing_inconsistency.py # interpret with Python
zero_len is False in Python.
non_zero is False in Python.