ensures is a simple Python package that implements the idea of Design by Contract described in the Pragmatic Paranoia chapter of The Pragmatic Programmer. That's the chapter where they say you should trust nobody, not even yourself.
- Verification of lists of pre/post condition and invariant functions.
- Usage of arbitrary functions for such verification.
- Result-type return values.
pip install ensuresRuns a list of functions on all args.
Returns Error if any of them fails.
from ensures import precondition
def is_positive(x):
"""Check if a number is positive."""
return x > 0
@precondition(is_positive)
def square_root(x):
"""Calculate square root with precondition that x must be positive."""
return x**0.5Runs a list of functions on the result.
Returns Error if any of them fails.
from ensures import ensure
def result_is_even(result):
"""Check if result is even."""
return result % 2 == 0
@ensure(result_is_even) # Using the alias
def double_number(x):
"""Double a number with postcondition that result is even."""
return x * 2Runs a list of functions on all args.
Returns Error if any of them fails.
from ensures import invariant
@invariant(lambda x: x >= 0) # Simple lambda invariant
def increment_counter(x):
"""Increment a counter with invariant that it stays non-negative."""
return x + 1Pattern matching is supported to unpack the Return value.
from ensures import Error, Success
result1 = square_root(1)
result2 = square_root(-1) # This will return an Error instance
def handle_result(res):
match res:
case Success(value):
print(f"Square root calculated: {value}")
case Error(func, args):
print(f"Precondition failed in {func.__name__} with args {args}")
handle_result(result1)
handle_result(result2)Check examples.py
Contract validation adds minimal overhead:
- Precondition: ~7x baseline function call
- Postcondition: ~8x baseline function call
- Memory: Constant memory usage, no leaks
See performance benchmarks for detailed analysis.
We welcome contributions! Please see our Contributing Guide for details.
See CHANGELOG.md for a list of changes in each version.
This project is licensed under the GPL-3.0-or-later License - see the LICENSE file for details.
