Assert in Python
Overview
In Python Programming, we have a particular keyword called Assert. It simply takes input a boolean condition, which when returns true doesn't return anything. Still, if it is computed to be false, it raises an AssertionError along with an optional message.
Introduction to Assert in Python
Multiple times during programming, the programmer knows that there are certain conditions or assumptions that are always going to be True. If at any point of time during the execution of the program, any statement with the condition that is meant to be True evaluates to False, then it shouldn’t allow the code to execute further. Essentially, we immediately terminate the program as soon as we find something fishy, that shouldn’t exist. This task is achieved with the help of assert.
What is Assert?
An assert statement can be used to verify any logical assumptions you make in your code. It is mainly used as a debugging tool. For example, if we write a function that performs division, we know that the divisor must not be zero, so we “assert” that the divisor shouldn’t be equal to zero so as to prevent any kinds of errors/bugs that could occur due to this problem in the code later on.
As input, the assert in Python takes an expression that is to be evaluated, and [an error message, which is optional. Basically, when the code encounters any assert statements, one of two things can happen.
One, the code runs without any issues; two, it throws an AssertionError, terminating the program. We are going to delve deep into these situations, but we must first understand why exactly the assert statement should be used.
Why Use Assert in Python?
An assert statement in Python recognizes issues right off the bat in your program, where the reason is clear, instead of later when some other operation fails.
They can be termed as internal self-checks for your code. The aim of using the assert statements is so that developers can track the root cause of the bug in their code quickly.
Assert statements particularly come in handy when testing or assuring the quality of any application or software.
Python Assert Statement
Syntax:
As stated above, we have a condition and an error message as part of the assert statement. If the condition used in the assert statement evaluates to True, the code runs normally i.e. without throwing errors or terminating the program. On the other hand, if it evaluates to False (unwanted condition) it throws an AssertionError along with the error message, if provided and terminates the program.
Assert in python,
is almost similar to this:
What is __debug__ here? It is a constant that is used by Python to determine if statements like assert must be executed.
In the Python programming language, whether we use the assert statement, or raise the error using if, it does not have any major differences, they’re almost similar. The code with if raises an AssertionError when the debug mode is on (__debug__ == True), and the condition provided evaluates to False.
When we can use an if statement, which is definitely easier to understand, why boggle minds with the assert statement? There are two main reasons – readable code, and the option of disabling the assert statements if required.
Using the assert statement instead of the if condition makes the code more readable and shorter. An advantage of using the assert statement over the if condition is that an assert statement can be disabled, unlike an IF condition.
To disable any assert statements in the program, running Python in optimized mode (__debug__ == False), ignores all assert statements. The -O flag can be passed for the same.
python -O program.py
Now that we have seen the syntax of the assert statement, as well as its advantage over if, let us move on to see what it looks like in the Python shell, and how we run it:
If the assertion fails, a message can be printed like this as done in the shell example above :
Not adding the error message does not make any difference in the way the program runs. The error displayed will be the Traceback error as shown in the example above and terminates the program. It just helps understand the assertion error more clearly.
Assertion errors in Python terminate the program you have written, but, what if we did not want that to happen? What if we want the code to run as-is, and along with it, we would like the error to be detected?
The solution for this problem is the try-except block. The try-except block in Python is another means of handling and checking errors in Python. First, only the code that is written inside the try block will get executed when there isn’t any error in the program and the except clause is skipped. While in the presence of an error in the try block, the code in the except block will be executed and code in the try block will be skipped.
Here’s how we handle a basic division by 0 assertion error using the try-except block:
Let’s try and understand what happened in the above code. We used an assert statement, that, as we read above prints an error message upon evaluation of the condition to False, and we also print a msg in the except block. What are we doing here, and why?
When we’re in the try block, we have values of x as 1 and y as 0, and an assert condition that prevents the division of any number by 0. Now since the value of y is 0, our assert statement evaluates to False and hence throws an AssertionError. We know that these errors terminate the program, but since we do not want it to terminate, we use the try-except. As soon as there is an error in the try block, we immediately move to the except block to handle the errors.
When we write a simple assert statement with a condition and an error message, what gets printed? The error message. So, the except block
The first statement with the parentheses will not work because you’re essentially providing the assert statement with a tuple. The format of a tuple in Python is (Val1, Val2, …) and any tuple written in the context of bool is always true unless it does not contain any values. This means that if we do not provide any condition to the assert statement, like :
assert()
it will raise an AssertionError because empty tuples are False.
What Does the Assertion Error do to our Code?
Upon reading and understanding multiple times that unhandled assertions terminate programs, a question comes to mind – How will it terminate the program?
There are essentially two ways of stopping the execution of a program – by exit() and by abort().
When a program is terminated by using exit(), the function performs – flushing of unwritten buffered data, closing of open files, and removal of temporary files and it returns an integer exit status to the operating system.
The abort() function may not close any files that are open, may not flush stream buffers, and may also not delete any temporary files. One major difference between both kinds of functions that terminate a program is that abort() results in abnormal termination while exit() causes normal termination.
Termination of the program due to an assert statement occurs with the help of the abort() function when the condition mentioned in the assert statement returns False.
Finally, now that we know what assert is, why it is useful, and how we can tackle it, we must address the elephant in the room. Where exactly can you use it?
Where do We Use Assert in Python?
Assertions are not used to flag expected error conditions, similar to “file not found” where a user can make a restorative move (or simply attempt once more). Instead, the assert statement is used mainly for debugging purposes,
1. Checking parameter types / classes / values
The assert statement can be used if your program has the tendency of controlling every parameter entered by the user or whatever else
Example:
2. Checking “can’t happen” situations
While the assert statement is useful in debugging a program, it is discouraged when used for checking user input unless it corrupts a universal truth. The statement must only be used to identify any “this should not happen” situation i.e. a situation where any fact, or a statement that is definitely True, becomes False due to a bug in the code.
For example, if the user enters fewer characters than required in the input, then it cannot be termed as a “this should not happen” situation, where the use of the assert statement is a must because the user isn’t violating any fact that is meant to be True always. It is not a blunder to use an assert statement for trivial issues such as this, but it is considered a bad practice.
However, if say, a program involves calculations with radius and diameter of a circle and the radius of the circle isn’t half of the diameter at any point in the program, then this comes under the “this should not happen” case, as it is a fact that cannot be changed or violated.
For example,
If during the complex operations, the value of the radius changes and is unequal to half of the diameter, our assert statement condition immediately detects it and throws an error so as to avoid any further complications/errors in the code or provide unwanted output.
3. Documentation of Understanding
Using the assert statement in your code is useful for documenting the programmer’s understanding of the code. It makes the programmer’s assumptions clear for themselves, as well as anyone else who works on the same code in the future. If for any reason, in the future the code gets broken, the reason for failure will be obvious, and the next time the assert condition evaluates to False, the caller will get the AssertionError exception.
Another Example of Assert in Python
Say you have a function that calculates the cost of an item after a discount. In this situation, we can positively say that the discounted cost will definitely be greater than 0 and lesser than the original cost.
If the discounted cost doesn’t lie in this range, then we are in a “this should not happen” situation. Hence, we use the assert statement.
Conclusion
- Assertions or assert in Python help you state facts with confidence in a program, it helps verify logical assumptions in any code
- Syntax for assert statement in Python:
- Error message in the code is optional but is written to provide a clear-cut understanding of why the error was raised
- Unhandled assertion errors terminate the program using abort(), but they can be handled using the try-except block if we do not want to terminate the program
- If the condition used in assert statement == False, an AssertionError() is thrown, but the code runs smoothly when the condition evaluates to True
- Assert statements in Python can be used for:
- Debugging purposes
- Checking “Can’t happen” situations
- Documentation of understanding
- Internal invariants
- Python Assert statements must not be used with parentheses, or for basic user input validation. They must be used in a “this should not happen” case.