Is the shortcircuit behaviour of Python's any/all explicit?

Solution 1:

The behaviour is guaranteed. I've contributed a patch, which was accepted and merged recently, so if you grab the latest sources you will see that the short-circuiting behaviour is now explicitly enforced.

git clone https://github.com/python/cpython.git
grep Short-circuit cpython/Lib/test/test_builtin.py

Solution 2:

The docs say

"Return True if any element of the iterable is true. If the iterable is empty, return False. EQUIVALENT TO:" (emphasis mine) ...

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

If any didn't short circuit, it wouldn't be EQUIVALENT to the posted code since the posted code clearly short circuits. You could consume more of a generator than you want to for example. In light of that, I say that the short circuiting behavior is guaranteed.

The exact same argument could be made for all.

Solution 3:

In case you landed here looking for "do any/all always always short-circuit?"

They do, but there is a gotcha: using a list comprehension can make it seem like you are overriding the short-circuiting behavior:

def hi():
    print('hi')
    return True

>>> any(hi() for num in [1, 2, 3, 4])
hi

>>> any([hi() for num in [1, 2, 3, 4]])
hi
hi
hi
hi

The list comprehension executes before any() does.

(Note: This does not answer the OP's very different question. This is the only stackoverflow page that comes up for me when searching "any all short circuit python.")

Solution 4:

It HAS to short circuit, since it could be given an unbound iterable. If it did not short circuit then this would never terminate:

any(x == 10 for x in itertools.count())