I read everywhere that Python all and any functions support short-circuiting.
However:
a = None
all((a is not None, a + 1 > 2))
Throws the following error:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/IPython/core/interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-4-6e28870e65c8>", line 1, in <module>
all((a is not None, a + 1 > 2))
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
I would have expected the code not to evaluate a + 1 > 2 since a is None.
Why is this happening? Is this because each term is evaluated before the call? Am I forced to use the and operator as in a is not None and a + 1 > 2?
The tuple
(a is not None, a + 1 > 2)needs to be created beforeall()can be called. It is during the creation of the tuple that theTypeErroris raised.all()doesn't even get a chance to run.If you want to see
all's short circuiting in action, pass it a generator expression. For example:In the first run
allstops when it hits the'R'.islower()case since that'sFalse. In the second run it keeps going untili == 6, which triggers an index error.I wouldn't say "forced"—I'm sure there other convoluted options—but yes, that's the obvious and idiomatic way to write it.