The assert statement is useful when your code reaches a point where a certain condition should already be true. You can use it to check that assumption and raise an `AssertionError` when the condition fails, which can expose logic errors closer to where they originate.
However, assert is meant for checking assumptions within your code, not every condition that can go wrong. Python can disable assertions when running in optimized mode, which makes them unsuitable for input validation, business rules, and other checks that must always run.
How you use assert, therefore, depends on what you are trying to verify and whether that check can safely disappear from execution.
What is Assert in Python?
In Python, the assert statement is a built-in construct that allows you to test assumptions about your code. It acts as a sanity check to ensure that certain conditions are met during the execution of a program.
The assert statement takes the following syntax:
assert condition, message
Output with Example –
Here, the condition is the expression you want to test, while the message is an optional string that provides additional information if the assertion fails.
When Python encounters an assert statement, it evaluates the given condition. If the condition is True, the program continues execution normally. If the condition is False, Python raises an AssertionError.
How Does Assert Work in Python?
When Python encounters an assert statement, it evaluates the condition that follows it. If the condition evaluates to True, nothing happens and the program moves to the next statement. If it evaluates to False, Python raises an AssertionError.
For example:
age = 20 assert age >= 18, "Age must be at least 18"
Output –
Since the condition is true, execution continues. If age were 15, the assertion would fail:
AssertionError: Age must be at least 18
Output –
Python assertions are also tied to the built-in __debug__ constant. Under normal execution, __debug__ is True, so assertions are evaluated. When you run Python with the -O optimization flag, __debug__ becomes False and assert statements are not executed.
python -O script.py
Output –
This behavior is why you should only use assert for checks that can safely be removed. Any validation or application logic that must always run should use explicit conditions and exceptions instead.
Assertions vs Exceptions
While assertions and exceptions can both stop normal execution when something goes wrong, they serve different purposes.
Assertions are used to check assumptions about the internal state of your code. If an assertion fails, it usually points to a programming error or a condition that should not have been possible.
assert len(data) > 0, "Data list should not be empty"
Output –
Exceptions are used for conditions that can legitimately occur while the program is running, such as invalid input, a missing file, or a failed network request.
try:
result = 10 / divisor
except ZeroDivisionError:
print("Cannot divide by zero")Output –
The key difference is that assertions can be disabled with Python’s -O flag, while exception handling remains active. So, use assert for internal assumptions and use exceptions for errors your application may need to handle.
| Aspect | Assertions | Exceptions |
|---|---|---|
| Primary purpose | Verify assumptions about the internal state of the program | Handle errors and conditions that can occur during normal execution |
| When to use | When a condition should always be true if the code is working correctly | When the program needs to respond to an error or unexpected condition |
| What failure indicates | Usually a programming error or broken assumption | A runtime problem that the application may be able to handle |
| Failure behavior | Raises an AssertionError | Raises an exception of the relevant type |
| Error handling | Typically used to expose a bug rather than recover from it | Can be caught with try-except so the program can recover or respond |
| Production use | Should not be used for checks that must always execute | Suitable for handling runtime failures in production |
| Can be disabled | Yes. Assertions are removed when Python runs with the -O flag | No. Exception handling remains active |
| Common examples | Checking invariants, internal states, and expected intermediate results | Handling invalid input, missing files, unavailable resources, or network failures |
When to Use Assert in Python?
Use assert when a failed condition would point to a bug or an incorrect assumption in your code. Good use cases include:
- Checking preconditions: Verify that an internal value is in the expected state before the next operation runs.
- Validating invariants: Confirm that a condition that should remain true throughout execution still holds.
- Checking postconditions: Verify that a function or operation produced a result within the expected range or state.
- Catching impossible states: Flag code paths that should never be reached if the program logic is correct.
- Debugging intermediate results: Check values at important points in a calculation or workflow to find where the logic starts to fail.
- Writing tests: Use assertions to compare actual results with expected results and fail the test when they do not match.
The main rule is simple: use assert for conditions that indicate a programming error when they fail. If the condition must always be checked at runtime, use explicit validation or exception handling instead.
When Not to Use Python Assertions?
Do not use assert for conditions that must always be checked while the application is running. Since assertions can be disabled, they are not suitable for validation, error handling, or application logic that your program depends on.
- Validating user input: Use explicit validation for data entered by users or received from external sources.
- Handling runtime errors: Use exceptions for conditions such as invalid values, missing files, failed requests, or unavailable resources.
- Enforcing business rules: Checks related to permissions, payment limits, account states, or other application rules must always execute.
- Performing critical production checks: Do not rely on assertions to prevent invalid or unsafe states in production code.
- Processing or sanitizing data: Validation and cleanup should happen through normal application logic, not through assertions.
- Controlling program flow: The behavior of your program should not depend on whether an assertion passes or fails.
A useful rule is to ask what happens if the check disappears. If that could change the program’s expected behavior, assert is not the right choice.
How to Use the Assert Statement in Python
The assert statement checks a condition and raises an AssertionError when that condition evaluates to False.
Syntax
assert condition, "Error message"
Output –
- condition: The expression you expect to evaluate to True.
- Error message: An optional message that explains why the assertion failed.
1. Using Assert in Your Code
Place an assert statement where you want to verify that a condition still holds.
x = 10
assert x > 0, "x must be positive"
print("Assertion passed.")Since x is greater than 0, the program continues and prints:
Assertion passed
If the condition fails:
x = -5
assert x > 0, "x must be positive"
print("This line will not run.")Python raises:
AssertionError: x must be positive
Output –
2. Using Assertions in Python Functions
Assertions can also be placed inside functions to check assumptions about the values the function is working with.
def divide(a, b): assert b != 0, "Denominator must not be zero" return a / b print(divide(10, 2))
Output –
This works when b is non-zero. However, this example is suitable only when b != 0 is an internal assumption. If b comes from user input or another external source, use explicit validation instead of assert.
3. Handling AssertionError
An AssertionError can be caught like any other exception:
try:
x = -10
assert x > 0, "x must be positive"
except AssertionError as e:
print(f"Assertion failed: {e}")Output –
In most cases, though, assertions are meant to expose bugs rather than recover from them. Catching AssertionError routinely can hide the problem the assertion was meant to surface.
4. Disabling Assertions
Python skips assertions when you run a program with the -O optimization flag:
python -O script.py
Any check written with assert should therefore be safe to remove. If the check must always run, use an if condition and raise an appropriate exception instead.
Flowchart of Python Assert Statement
The flowchart below follows the execution of an assert statement. Python evaluates the specified condition and continues to the next statement when the result is True. If the condition evaluates to False, it raises an AssertionError and includes the custom error message when one has been provided.
Practical Applications of Assert in Python
Assertions are most useful when they check assumptions about the internal state of your program. Here are some common ways to use them.
1. Checking Preconditions
A precondition is something you expect to be true before a block of code runs. For example, if a function works only with values generated internally by your application, you can use assert to catch an unexpected value.
def calculate_discount(price, discount): assert price > 0, "Price must be positive" assert 0 <= discount <= 1, "Discount must be between 0 and 1" return price * (1 - discount) print(calculate_discount(100, 0.2))
Output –
Use this approach only when the values are controlled by your code. If price or discount comes directly from a user, API, or another external source, use explicit validation instead.
2. Verifying Invariants
An invariant is a condition that should remain true while a program or operation runs. Assertions can flag the exact point where that expected state is broken.
balance = 1000 balance -= 200 assert balance >= 0, "Balance should not be negative"
Output –
This is useful when later code depends on an internal state that earlier operations are expected to preserve.
3. Verifying Postconditions
A postcondition checks whether an operation produced the expected type or state of result.
def square(number): result = number * number assert result >= 0, "Result should be non-negative" return result
Output –
Here, a failed assertion would indicate that the result violates an assumption made about the operation.
4. Debugging Intermediate States
In a longer calculation or data-processing flow, an assertion can help identify where an unexpected value first appears.
def process_data(data):
assert isinstance(data, list), "Data should be a list"
for item in data:
assert isinstance(item, int), f"Unexpected value: {item}"
return [item * 2 for item in data]Output –
Instead of discovering the problem after several more operations have run, the assertion points to the state that first violated the expectation.
How to Use Assert in Python Testing
Assertions are central to testing because they define the result you expect from the code under test. The way you write them depends on whether you are using plain Python, pytest, or the unittest framework.
1. Using Plain Assert Statements
For simple test functions, you can use Python’s standard assert statement to compare the actual result with the expected result.
def multiply(a, b): return a * b def test_multiply(): assert multiply(2, 3) == 6 assert multiply(-1, 5) == -5 assert multiply(0, 10) == 0
Output –
If any condition evaluates to False, Python raises an AssertionError.
2. Using Assert with pytest
pytest lets you use standard Python assert statements directly. When an assertion fails, it provides additional information about the values involved, which can make the failure easier to investigate.
def test_total(): total = 10 + 15 assert total == 25
You can also use pytest.raises() when the expected behavior is an exception:
import pytest
def test_invalid_conversion():
with pytest.raises(ValueError):
int("abc")Output –
3. Using Assertions with unittest
Python’s unittest framework provides dedicated assertion methods instead of relying only on the assert statement.
import unittest class TestMath(unittest.TestCase): def test_multiply(self): self.assertEqual(2 * 3, 6) self.assertGreater(10, 5) self.assertIsNone(None)
Output –
Methods such as assertEqual(), assertTrue(), assertIn(), and assertRaises() make the expected relationship explicit and provide failure information when a test does not pass.
The important difference is that assertions used by testing frameworks are part of the test itself. Python’s assert statement inside application code is primarily used to check internal assumptions while the program executes.
Common Conditions You Can Check With Assert
Python does not have separate types of assert statements. The same statement can check different kinds of conditions depending on the expression you provide.
1. Value Checks
Use assert to verify that a value matches an expected result or falls within an expected range.
assert x == 5 assert score >= 0 assert result in expected_results
Output –
2. Type Checks
You can check whether an internal value has the type your code expects.
assert isinstance(x, int) assert isinstance(my_list, list)
Output –
If the value comes from an external source and its type must be validated, use explicit validation instead.
3. Collection Checks
Assertions can verify assumptions about lists, dictionaries, sets, and other collections.
assert item in my_list assert key in my_dict assert len(results) > 0
Output –
These checks are useful when your code expects an earlier operation to have populated or modified a collection in a specific way.
4. Boolean Conditions
Any expression that evaluates to True or False can be used in an assert statement.
assert x > y assert user.is_active assert start_date < end_date
You can also combine multiple conditions:
assert x > 0 and x < 100
OutPut –
However, keeping each assertion focused on one assumption usually makes failures easier to identify.
Assert in Python: Example
Here is a complete example of using assert to check an assumption inside a function:
def calculate_average(numbers): assert len(numbers) > 0, "List must not be empty" total = sum(numbers) average = total / len(numbers) return average data = [5, 10, 15, 20] result = calculate_average(data) print(result)
Output –
The function assumes that numbers contain at least one value. When that assumption holds, it calculates and returns the average.
If an empty list reaches the function, the assertion fails before Python attempts the division:
data = [] result = calculate_average(data)
Python then raises:
AssertionError: List must not be empty
Output –
This use of assert is appropriate only if an empty list represents a programming error. If the list can legitimately be empty because it comes from user input, an API, or another external source, the function should handle that case with explicit validation instead.
Common Mistakes and Misconceptions with the Assert Statement in Python
Most problems with assert come from using it for checks that should always run or from assuming it behaves like regular validation.
1. Using Assert for Input Validation
Assertions are not reliable for validating user input or external data because Python can remove them in optimized mode.
assert age >= 18, "User must be at least 18"
If this check controls whether a user can continue, use explicit validation instead:
if age < 18:
raise ValueError("User must be at least 18")Output –
2. Using Assert for Runtime Error Handling
An assertion should expose a broken assumption, not replace try-except.
For example, a missing file or failed network request can occur during normal execution. These cases should be handled with exceptions so the program can respond appropriately.
3. Putting Side Effects Inside Assert
Avoid calling functions inside an assertion when those functions perform work your program depends on.
assert save_data()
When Python runs with -O, the entire assertion is skipped, which means save_data() may never run.
Keep side effects separate:
saved = save_data() assert saved
Output –
4. Using Parentheses Incorrectly
A common mistake is writing an assertion like this:
assert (x > 0, "x must be positive")
This creates a tuple. Since a non-empty tuple is truthy, the assertion will pass even when x > 0 is false.
Write it as:
assert x > 0, "x must be positive"
5. Using Assert to Enforce Argument Types
Using assert as a form of runtime type enforcement is unreliable because the check can disappear in optimized mode.
assert isinstance(value, int)
Output –
This is reasonable when the type is an internal assumption. If your function must reject invalid input at runtime, use explicit validation and raise TypeError instead.
Best Practices for Using Assert in Python
Assertions are most effective when each one checks a clear internal assumption and a failure points directly to a problem in the code. Keep the following practices in mind:
- Use assert for programming errors: Reserve assertions for conditions that should never fail when the code is working correctly.
- Keep conditions simple: An assertion should be easy to read and understand. Avoid complex expressions that make it difficult to identify why the condition failed.
- Write useful error messages: Add enough context to explain which assumption failed, especially when the condition alone does not make the problem obvious.
- Avoid side effects: Do not put operations inside an assertion if your program depends on them being executed. The entire statement may be skipped in optimized mode.
- Check one assumption at a time: Separate unrelated conditions so a failed assertion clearly identifies what went wrong.
- Use assertions to document internal expectations: A well-placed assertion can show other developers what state the code expects at a specific point.
- Keep assertions enabled during testing: Run development and test environments without the -O flag so assertion failures are not skipped.
- Use explicit validation for external data: User input, API responses, files, and other external data should be validated with regular conditions and appropriate exceptions.
The simplest test is to consider what happens if Python removes the assertion. If the program can no longer behave correctly or safely, that check should not be implemented with assert.
Conclusion
assert works best when a failed condition means there is a problem in the code itself. If a value has reached an impossible state or an operation has produced a result that should not occur, an assertion can stop execution at the point where that assumption breaks.
But if the condition can fail during normal use, handle it explicitly. User input can be invalid. Files can be missing. API requests can fail. These are situations your application needs to deal with, not assumptions for assert to enforce. Keeping that difference clear is enough to avoid most of the common mistakes developers make with Python assertions.



























