Search code examples
pythonbuilt-innonetypeshort-circuiting

Python 2 and Python 3 built-in all() function not behaving equally


The following code:

a = None
b = None
all([a, b, a > b]) # Returns False in python 2 but TypeError in python 3

Error in python 3:

TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'

It seems like the python 2 version is short circuiting but the python 3 version is not. Is this the case? Why is this happening? Is it a bug? Should I report it?

I've tested this code in Python 2.7.17, 3.6.9 and 3.8.2


Solution

  • Short circuiting is irrelevant. The whole list is evaluated before all is executed.

    Python 2 is more permissive with its comparisons. In Python 2 you can use < between strings and ints, lots of different types of objects, and None, without an error. In Python 3, the rules were tightened up so you can only use < in cases where it has a clear meaning.

    If the functionality you need is

    a and b and a > b
    

    then I suggest you use that. For that expression, a > b will not be evaluated if a or b is None.