
Before the introduction of bool and also in other languages, `not not x` was/is used to convert to True (1) and False (0). However, the old way is still much faster than bool(x) or even operator.truth(x). Test:
py -3.10 -m timeit -s "objects = 1, 0, -0.0, "20", "False", 93, 28.569, [], set(), {1: 5}" "[(not not x) for x in objects]" 200000 loops, best of 5: 1.12 usec per loop py -3.10 -m timeit -s "objects = 1, 0, -0.0, "20", "False", 93, 28.569, [], set(), {1: 5}" "[(bool(x)) for x in objects]" 200000 loops, best of 5: 2.32 usec per loop py -3.10 -m timeit -s "from operator import truth; objects = 1, 0, -0.0, "20", "False", 93, 28.569, [], set(), {1: 5}" "[(truth(x)) for x in objects]" 200000 loops, best of 5: 2.04 usec per loop py -3.10 -V Python 3.10.0rc1
That's nearly 52%/46% faster! I guess the name lookup and the FUNCTION_CALL is slower than UNARY_NOT. So actually, using `not not` is an optimize, although it isn't clear. This is interesting.