Let’s say that you were given an ugly boolean expression to evaluate. Assume in the following statement that the ugly part resides in
X, which can be thought of as a very large boolean expression that would take some time (i.e. seconds) to evaluate:
If we take a deeper look, we will notice that no matter what
X will evaluate to, the statement will always return
Fortunately, Python uses a technique called short-circuit evaluation to speed up the process of such boolean expression. So, what will Python do in the above statement is it will notice that the result of the expression does not depend on
X at all, and will thus return
False immediately without evaluating
X. The above statement is called logical conjunction (i.e.
Another example where short-circuit evaluation could be used is in the following example:
In this case, Python will evaluate the first part of the
if-condition. If it evaluates to
False, it won't bother moving to the second part since we will always get
False. This example is called a conditional expression.
Circuit breaking protocol
Nick Coghlan and Mark E. Haase proposed a new protocol (PEP 532) that mainly aims to enhance the way we build short-circuited expressions in a more elaborative way. It tries to give the left-hand operand access to a short-circuiting operation.
Let’s take this simple conditional expression and see how it would be interpreted using the new protocol:
The new protocol would do the following (I will explain what’s happening in a moment):
We can notice that the interpreter would only access the protocol method (i.e.
__then__) of the conditional expression branch that is actually executed, provided that the method look up would be via the circuit breaker's type.
The term circuit breaking is analogous to what is happening in the electrical domain, such that the same way circuit breakers in electrical systems detect and handle short circuits before they make any harm, circuit breakers in Python detect and handle short circuits in expressions before triggering any exceptions.
Circuit breaking operators IF and ELSE
There are two circuit breaking operators, the right-associative and the left-associative circuit breaking operators.
For the statement:
The right-associative circuit breaking operator would be as follows:
In this protocol, the statement would be:
On the other hand, the left-associative circuit operator which is written as follows:
could be written using the protocol as:
What we can notice from the above two cases is that when the circuit breaking expression would short-circuit, the condition expression would be the
_result, unless of course it is a circuit breaker.
It is also important to note that the natural output is the right-associative operator since the right operand is always evaluated first, and the left operand is not evaluated at all if the right operand was
True (i.e. in a boolean context).
An example on circuit breakers is
operator.if_false (notice that they are the logical inversions of each other).
Hooking into Python’s
OR boolean operators
The way Python’s
or boolean operators currently short-circuit is that if the outcome could be determined from the left-operand, then there is no need to evaluate the right-hand operand.
So, the following expression won’t raise an exception even though the right-hand expression raises a
ZeroDivisionError exception if it was evaluated:
As mentioned at the beginning of this article,
PEP 532 is trying to give the left-hand operand access to a short-circuiting operation. For instance, the
else operator this PEP proposes enables the left-hand operand to handle the outcome based on its truth value.
LHS (Left-Hand Side) is:
RHS (Right-Hand Side) is:
In the following expression:
print('https://abder.io') else print('')
LHS is given access to both LHS and RHS based on the value of
What will happen is the PEP will use the introduced
__else__ methods in such a way that the following statement will be called if LHS is considered
On the other hand, if RHS is True, the following statement will be called:
This can be written as follows:
If we want to implement the above, we can do the following:
De Morgan’s laws
De Morgan’s laws define the interpretation of expressions involving the boolean operators:
De Morgan’s law for
not (a and b) == (not a or not b)
not (a or b) == (not a and not b)
De Morgan’s laws are mentioned here since the short-circuiting operators allow multiple ways to write the same expression. Thus, through De Morgan’s laws we are able to express the results of
or in terms of each other, in addition to a suitable combination of
In terms of Python,
or can be written as follows:
assert in Python simply evaluates the expression and takes no action if the expression succeeds, otherwise it will raise an
This also holds to the short-circuiting operators, such that:
The circuit breaking protocol enhances the way we build short-circuited expressions, as it tries to give the left-hand operand access to a short-circuiting operation. The protocol allows us to hook into Python’s
or operators by allowing the left-hand operand to handle the outcome based on the truth value.