Python Assert Statements

Assert statement in Python

Assert statements in Python make sure a condition is met before continuing the execution of the program.

For example, let’s assert that a discounted price does not go below 0 nor surpass the original price:

def discount(price, dc):
    new_price = int(price * (1.0 - dc))

    assert 0 <= new_price, "Price is less than 0."
    assert new_price <= price, "Price is more than original price"

    return new_price

Calling this function with an input that makes the assertion fail will lead to the code crash with a clear error:

price = 125
dc = 1.3 # 130% discount

discounted_price = discount(price, dc)

print(discounted_price)

Output:

Traceback (most recent call last):
  File "example.py", line 10, in <module>
    discounted_price = discount(price, dc)
  File "example.py", line 3, in discount
    assert 0 <= new_price <= price
AssertionError: Price is less than 0.

You should only do assertions when debugging your code. Do not leave assert statements in a production environment.

In this guide, you will learn how to adapt assertion as one of your debugging routines. You are going to see some real-life use cases of assertion in Python. And you will also see an example of when assertion can be really dangerous.

Assertion in Python

Debugging code helps you track down bugs that cause issues.

When you debug a program, there are times when you want to test for specific conditions. More specifically, if the condition is not met, the program should throw an error instead of continuing. This way you can narrow down the root cause of a bug and save your time when debugging code.

Python’s built-in assert statement is the right solution for this. The assert statement is used to handle errors during debugging phase.

You can use Python’s built-in assert statement to debug your code.

Assertion informs a developer of an unrecoverable error. Thus, the assertion is not intended to point out regular error conditions like “File not found”.

You should use assertions to declare conditions that should be impossible in your code. If one of these impossible conditions does not hold, it means there’s a bug in your code.

If a condition you assert is True, the program continues. If the condition evaluates False, an error called AssertionError is thrown.

If your program code has no bugs, these impossible conditions never become True. But if one occurs, the program crashes with an AssertionError telling you exactly which “impossible” condition was triggered.

Thus assertion makes it much easier to track down and fix bugs in your programs.

Use Assertions Cautiously in Python

Use assertions cautiously, only when debugging your code.

Assertion helps you find the root cause of a bug. Unlike regular runtime errors in Python, assertions have to be manually defined by a developer. So the assertion is not a regular error handling procedure.

It is possible to disable assertion statements when using a Python interpreter. Thus there can be problems if you rely on assertions, because they may not be triggered at all.

The assert Statements in Python

The assert statement checks if a condition evaluates True.

  • If it does, the program keeps running.
  • If it does not, the program returns an AssertionError and the program stops executing.

In Python, assert is a reserved keyword. It follows this syntax:

assert condition, message

Where the two parameters are:

  • condition: the condition agains which you test your code.
  • message: the message you want to show if the assertion fails. This is an optional parameter that you do not need to specify if you don’t need one.

Using assert is roughly equal to the following if statement:

if not condition:
    raise AssertionError(message)

The only difference is that assert statements can be disabled by running the program with an -O flag.

But the assert statement means checking if a condition is not True only in the debug mode. So in reality, the assert statement is equivalent to the following:

if __debug__:
    if not condition:
        raise AssertionError(message)

Even though this is a subtle difference, it highlights why you should only use assertion in debugging. If the debug mode is disabled, assertions do not get triggered, and the code with potential bugs is free to execute.

Assert Example in Python

Let’s build a simple discount calculator.

This function takes a price of an item and a discount percentage as a fractional number.

def discount(price, dc):
    new_price = int(price * (1.0 - dc))

    assert 0 <= new_price, "Price is less than 0."
    assert new_price <= price, "Price is more than original price"

    return new_price

In this function, the assert statements make sure:

  • The discounted price is not less than 0
  • The discounted price is not more than the original price.

Now, let’s test how it works by calling the discount() function:

price = 125
dc = 0.3

discounted_price = discount(price, dc)

print(discounted_price)

Output:

87

So it seems to work as we intended.

Now, let’s input an invalid discount to the discount() function.

As you know, it would make no sense to give a discount that is more than 100%, or 1.0 when talking about fractional discounts.

Let’s see what happens when we input a 1.3 (130%) discount:

price = 125
dc = 1.3

discounted_price = discount(price, dc)

print(discounted_price)

Output:

Traceback (most recent call last):
  File "example.py", line 10, in <module>
    discounted_price = discount(price, dc)
  File "example.py", line 3, in discount
    assert 0 <= new_price <= price
AssertionError: Price is less than 0.

As you see from the above traceback, applying an invalid discount crashes the program with an AssertionError. With the help of this assertion error and the traceback, it is easy to track down what went wrong in our code.

In this case, it is the new price that dropped below zero, which means the discount was too high.

This is how the assert statement can really help you debug your code.

Assert Statement vs If Statement in Python

It may seem like the assert statement and the if statement does the same thing. They both check if a condition is True or False.

But there are key differences between assert and if statements in Python:

  • An if statement is a part of the logic of the code. The assert statement is used to validate input when debugging code.
  • If the if statement’s condition is False, the code continues from where we want it to. When an assert statement is False, an error is thrown and the code execution stops completely.
  • An if statement is always there. An assert statement can be disabled.

Assert Multiple Conditions

The point of assertion is to track down bugs and impossible conditions in your program with relative ease.

If you assert multiple conditions in a single assert statement, you only make the job harder. This is because you cannot determine which one of the conditions caused the bug.

If you want to push it, you can assert multiple conditions similar to how you check multiple conditions in an if statement.

For example:

assert 1 + 1 == 3 and 1 + 2 == 5, "Error occurred somewhere"

Output:

AssertionError: Error occurred somewhere

Python Assert Multiple Lines

If you want your assertion message to expand to multiple lines:

  1. Wrap the message around a set of parentheses.
  2. Break the lines as desired.
  3. Wrap each line into a set of single or double quotes.

For instance:

assert 1 + 1 == 3, (
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
    "Donec id magna id lectus gravida finibus. In gravida, mauris "
    "condimentum rhoncus sagittis, mi nisl lacinia tortor, non interdum "
    "nisl diam et lectus. Sed vitae ante vestibulum, volutpat neque non, "
    "vehicula erat. Nullam aliquam risus orci, blandit varius metus pulvinar id."
)

Output:

AssertionError: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id magna id lectus gravida finibus. In gravida, mauris condimentum rhoncus sagittis, mi nisl lacinia tortor, non interdum nisl diam et lectus. Sed vitae ante vestibulum, volutpat neque non, vehicula erat. Nullam aliquam risus orci, blandit varius metus pulvinar id.

Python Assert Statement—Do You Need Parentheses

Be careful with parentheses and assert. In Python 3, assert is a statement, not a function. Thus it does not take parenthesis.

Using assert with parenthesis like this is wrong:

assert(1 + 1 == 3, "An error occurred")

Instead, you should use it without parenthesis like this:

assert 1 + 1 == 3, "An error occurred"

The reason why the parenthesis-version does not work is the assertion always evaluates True. This is because, in the boolean context, any non-empty tuple evaluates True.

For instance, if you convert a tuple (1, 2) to a boolean, you get True:

bool((1, 2)) # Returns True

Or:

bool((1+1 == 3, "An error")) # Also returns True

As a result, if you write the assert statement with parenthesis, you are essentially writing assert(True).

The only way you can use parenthesis with the assert statement is by wrapping the condition to parenthesis but leaving the message out.

For example:

assert (1 + 1 == 3), "An error occurred"

Output:

AssertionError: An error occurred

This assertion works fine because the assertion is not applied to a tuple. Instead, it is applied on the condition.

Assertions Are Not for Data Validation in Python

The assert statements can be turned off in Python. So do not rely on assert statements for data validation. This can lead to big problems as these checks are omitted.

This is not a mistake by Python developers. Instead, it is an intentional decision. It is really dangerous to use assert as a shorthand way for data validation.

Imagine you’re building a social media app with Python. Somewhere in the code, you want to remove users as an administrator of the app. To do this, you assert that the current user is the administrator that has the privilege to delete users before actually deleting one.

Here is how your code would look like:

def delete_account(user_id, user):
    assert user.is_admin(), "Must be admin to delete"
    users.find_user(user_id).delete()

If you now take a closer look at this function, what do you think happens when the assertions are disabled?

It causes a serious issue.

Any user can delete any account given an user ID. This happens because the admin check is now a null operation due to assertions being disabled.

This kind of behavior would be catastrophic for your application.

But how can you avoid it?

Do not use assertions to do data validation. You can use a regular if statement instead.

For instance:

def delete_account(user_id, user):
    if not user.is_admin():
        raise AuthError("Must be admin to delete")
    users.find_user(user_id).delete()

This approach is also better as it:

  • Does not pose a security risk
  • Raises an AuthError, instead of a mysterious AssertionError.

How to Disable Assertions in Python

You can disable assertions in Python by executing your program file with -O flag. This sets the __debug__ to False.

For instance, given a Python program in a file called example.py you can disable the assertions by running the code with:

python -O example.py

Now no assert statements are triggered regardless of whether there was a bug or not.

Conclusion

Today you learned how Python assert statements works.

The assert statement in Python is meant to debug your code—not to handle runtime errors.

An assert statement can be thought of as a sanity check. It helps developers make sure what they think is true really is true.

Thanks for reading. Happy coding!

Further Reading

Python Tricks

How to Write to a File in Python

The with Statement in Python

Share on facebook
Share on twitter
Share on linkedin

Leave a Comment

Your email address will not be published.