The assert
statement in Python is a debugging aid used to test conditions that should always be true during development. If the condition evaluates to False
, it raises an AssertionError
, optionally with a message. It is not intended for production error handling but rather for catching programmer errors and validating assumptions.
Syntax
assert condition, "Optional error message"
- Condition: An expression expected to be
True
. - Message: Optional string to describe the failure (useful for debugging).
Key Use Cases & Examples
1. Validating Function Inputs
Ensure arguments meet preconditions:
def calculate_area(radius):
assert radius > 0, "Radius must be positive"
return 3.14 * radius ** 2
# Test
print(calculate_area(5)) # OK
print(calculate_area(-2)) # AssertionError: Radius must be positive
2. Checking Function Outputs
Verify postconditions after computation:
def split_list(items):
result = [items[:len(items)//2], items[len(items)//2:]]
assert len(result[0]) + len(result[1]) == len(items), "Split mismatch"
return result
split_list([1, 2, 3, 4]) # [[1, 2], [3, 4]] (no error)
# If split is incorrect, raises AssertionError
3. Testing Invariants in Data Structures
Ensure data integrity in a class:
class TemperatureSensor:
def __init__(self, temp_c):
self.temp_c = temp_c
assert -273.15 <= temp_c <= 1000, "Temperature out of valid range"
def set_temp(self, new_temp):
self.temp_c = new_temp
assert -273.15 <= self.temp_c <= 1000 # Re-check after update
sensor = TemperatureSensor(-300) # AssertionError
4. Debugging Complex Logic
Check intermediate states:
def process_data(data):
total = sum(data)
assert total >= 0, "Negative total after processing"
# ... more steps ...
process_data([10, -5, 3]) # Total = 8 (OK)
process_data([10, -15, 3]) # Total = -2 → AssertionError
5. Unit Testing (Simplified Checks)
Validate test cases (though dedicated testing frameworks like pytest
are better):
def test_addition():
result = 2 + 2
assert result == 4, "2 + 2 should be 4"
test_addition() # Passes silently; fails with AssertionError if broken
When to Avoid assert
- User Input Validation:
Useif
statements and raise proper exceptions (e.g.,ValueError
) instead, as asserts can be disabled.
# BAD (assert for user input)
age = int(input("Enter age: "))
assert age >= 0, "Age cannot be negative"
# GOOD (explicit check)
if age < 0:
raise ValueError("Age cannot be negative")
- Production Error Handling:
Asserts are stripped when Python runs in optimized mode (python -O
). Usetry/except
blocks instead.
Handling Assertions in Practice
Customizing Error Messages
Include context for easier debugging:
x = 5
y = 10
assert x > y, f"{x} is not greater than {y}"
# Output: AssertionError: 5 is not greater than 10
Disabling Asserts Globally
Run Python with the -O
(optimize) flag to ignore all assert
statements:
python -O script.py # All assertions are skipped
Common Pitfalls
- Overusing Asserts: Reserve them for debugging, not runtime checks.
- Side Effects in Conditions: Avoid changing state within an
assert
, as it won’t execute in optimized mode.
# Risky (deletes file only if asserts are enabled)
assert os.remove("temp.txt"), "Failed to delete file"
Summary Table
Scenario | Use assert ? | Alternative |
---|---|---|
Debugging internal logic | ✅ Yes | – |
Validating user input | ❌ No | raise ValueError |
Checking API responses | ❌ No | try/except blocks |
Unit testing | ✅ Yes (simple) | pytest /unittest |
Ensuring data invariants | ✅ Yes | Custom validation methods |
By strategically using assert
, you can catch bugs early and document assumptions in your code, but always pair it with proper error handling for production use!